gmio/src/datax_stl/stlb_read.c

122 lines
4.1 KiB
C
Raw Normal View History

#include "stl_io.h"
#include "stl_error.h"
#include "internal/stl_rw_common.h"
#include "internal/stlb_byte_swap.h"
#include "../datax_core/endian.h"
#include "../datax_core/error.h"
#include "../datax_core/internal/convert.h"
#include "../datax_core/internal/byte_swap.h"
#include <string.h>
FOUG_INLINE static void read_triangle_memcpy(const uint8_t* buffer,
2014-01-29 23:59:19 +08:00
foug_stl_triangle_t* triangle)
{
2014-01-29 23:59:19 +08:00
/* *triangle = *((foug_stl_triangle_t*)(buffer)); */
memcpy(triangle, buffer, FOUG_STLB_TRIANGLE_RAWSIZE);
}
2014-01-29 23:59:19 +08:00
static void foug_stlb_read_facets(foug_stl_geom_creator_t* creator,
2014-01-27 22:03:50 +08:00
const uint8_t* buffer,
2014-01-30 17:19:22 +08:00
const foug_stlb_readwrite_helper* rparams)
2013-01-25 01:38:43 +08:00
{
const uint32_t facet_count = rparams->facet_count;
const uint32_t i_facet_offset = rparams->i_facet_offset;
2014-01-29 23:59:19 +08:00
foug_stl_triangle_t triangle;
uint32_t buffer_offset = 0;
uint32_t i_facet = 0;
2013-01-25 01:38:43 +08:00
2014-01-29 23:59:19 +08:00
if (creator == NULL || creator->add_triangle_func == NULL)
2013-01-25 01:38:43 +08:00
return;
for (i_facet = 0; i_facet < facet_count; ++i_facet) {
/* Decode data */
read_triangle_memcpy(buffer + buffer_offset, &triangle);
buffer_offset += FOUG_STLB_TRIANGLE_RAWSIZE;
if (rparams->fix_endian_func != NULL)
rparams->fix_endian_func(&triangle);
/* Declare triangle */
2014-01-29 23:59:19 +08:00
creator->add_triangle_func(creator->cookie, i_facet_offset + i_facet, &triangle);
2013-01-25 01:38:43 +08:00
}
}
2014-01-29 23:59:19 +08:00
int foug_stlb_read(foug_stl_geom_creator_t *creator,
foug_transfer_t* trsf,
foug_endianness_t byte_order)
{
const foug_endianness_t host_byte_order = foug_host_endianness();
2014-01-30 17:19:22 +08:00
foug_stlb_readwrite_helper rparams;
uint8_t header_data[FOUG_STLB_HEADER_SIZE];
2014-01-27 22:03:50 +08:00
uint32_t total_facet_count = 0; /* Count of facets as declared in the stream */
int error = FOUG_DATAX_NO_ERROR; /* Helper variable to store function result error code */
2013-01-25 01:38:43 +08:00
2014-01-27 22:03:50 +08:00
/* Check validity of input parameters */
2014-01-30 17:19:22 +08:00
if (!foug_stlb_check_params(&error, trsf, byte_order))
return error;
/* Initialize rparams */
2014-01-30 17:19:22 +08:00
memset(&rparams, 0, sizeof(foug_stlb_readwrite_helper));
if (host_byte_order != byte_order)
2014-01-29 23:59:19 +08:00
rparams.fix_endian_func = foug_stl_triangle_bswap;
2014-01-27 22:03:50 +08:00
/* Read header */
if (foug_stream_read(&trsf->stream, header_data, 1, FOUG_STLB_HEADER_SIZE)
!= FOUG_STLB_HEADER_SIZE)
{
return FOUG_STLB_READ_HEADER_WRONG_SIZE_ERROR;
}
/* Read facet count */
2013-03-06 18:49:53 +08:00
if (foug_stream_read(&trsf->stream, trsf->buffer, sizeof(uint32_t), 1) != 1)
return FOUG_STLB_READ_FACET_COUNT_ERROR;
memcpy(&total_facet_count, trsf->buffer, sizeof(uint32_t));
if (host_byte_order != byte_order)
total_facet_count = foug_uint32_bswap(total_facet_count);
/* Callback to notify triangle count and header data */
2014-01-29 23:59:19 +08:00
if (creator != NULL && creator->binary_begin_solid_func != NULL)
creator->binary_begin_solid_func(creator->cookie, total_facet_count, header_data);
/* Read triangles */
2014-01-27 22:03:50 +08:00
while (foug_datax_no_error(error)
&& rparams.i_facet_offset < total_facet_count)
2014-01-27 22:03:50 +08:00
{
rparams.facet_count = foug_stream_read(&trsf->stream,
trsf->buffer,
FOUG_STLB_TRIANGLE_RAWSIZE,
trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE);
2013-03-06 18:49:53 +08:00
if (foug_stream_error(&trsf->stream) != 0)
2013-03-05 08:04:29 +08:00
error = FOUG_DATAX_STREAM_ERROR;
else if (rparams.facet_count > 0)
2013-03-05 08:04:29 +08:00
error = FOUG_DATAX_NO_ERROR;
2013-01-24 18:29:51 +08:00
else
break; /* Exit if no facet to read */
2013-03-05 08:04:29 +08:00
if (foug_datax_no_error(error)) {
uint8_t progress_pc;
2014-01-29 23:59:19 +08:00
foug_stlb_read_facets(creator, trsf->buffer, &rparams);
rparams.i_facet_offset += rparams.facet_count;
progress_pc = foug_percentage(0, total_facet_count, rparams.i_facet_offset);
2013-03-06 18:49:53 +08:00
if (!foug_task_control_handle_progress(&trsf->task_control, progress_pc))
2013-03-05 08:04:29 +08:00
error = FOUG_DATAX_TASK_STOPPED_ERROR;
}
} /* end while */
2013-03-06 18:49:53 +08:00
if (foug_datax_no_error(error)
2014-01-29 23:59:19 +08:00
&& creator != NULL
&& creator->end_solid_func != NULL)
2013-03-06 18:49:53 +08:00
{
2014-01-29 23:59:19 +08:00
creator->end_solid_func(creator->cookie);
2013-03-06 18:49:53 +08:00
}
if (foug_datax_no_error(error) && rparams.i_facet_offset != total_facet_count)
error = FOUG_STLB_READ_FACET_COUNT_ERROR;
return error;
}