Example #1
0
CachedPage::UnitPtr DiHdfRasterPager::fetchUnit(DataRequest *pOriginalRequest)
{
   VERIFYRV(pOriginalRequest != NULL, CachedPage::UnitPtr());
   unsigned int frame = pOriginalRequest->getStartBand().getOnDiskNumber();
   if (mHdf.toFrame(frame) == FAIL)
   {
      return CachedPage::UnitPtr();
   }
   const RasterDataDescriptor *pDesc = static_cast<const RasterDataDescriptor*>(getRasterElement()->getDataDescriptor());
   unsigned int bpp = pDesc->getBytesPerElement();
   size_t bufsize = pOriginalRequest->getConcurrentRows() * pDesc->getColumnCount() * bpp;
   char* pBuffer = new char[bufsize];
   int32 pStart[] = {pDesc->getActiveColumn(0).getOnDiskNumber(), pOriginalRequest->getStartRow().getOnDiskNumber()};
   int32 pCount[] = {pDesc->getColumnCount(), pOriginalRequest->getConcurrentRows()};
   int32 pStride[] = {1, 1};
   if (GRreadimage(mHdf.riid(), pStart, pStride, pCount, pBuffer) == FAIL)
   {
      delete pBuffer;
      return CachedPage::UnitPtr();
   }
   return CachedPage::UnitPtr(new CachedPage::CacheUnit(
      pBuffer, pOriginalRequest->getStartRow(), pOriginalRequest->getConcurrentRows(),
      bufsize, pOriginalRequest->getStartBand()));
}
Example #2
0
static int read_partial_array(const coda_cursor *cursor, long offset, long length, void *dst)
{
    int32 start[MAX_HDF4_VAR_DIMS];
    int32 stride[MAX_HDF4_VAR_DIMS];
    int32 edge[MAX_HDF4_VAR_DIMS];
    long i;

    switch (((coda_hdf4_type *)cursor->stack[cursor->n - 1].type)->tag)
    {
        case tag_hdf4_basic_type_array:
            coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading is not supported for HDF4 attributes");
            return -1;
        case tag_hdf4_GRImage:
            {
                coda_hdf4_GRImage *type;

                type = (coda_hdf4_GRImage *)cursor->stack[cursor->n - 1].type;
                stride[0] = 1;
                stride[1] = 1;
                if (length < type->dim_sizes[1])
                {
                    start[0] = offset / type->dim_sizes[1];
                    start[1] = offset % type->dim_sizes[1];
                    edge[0] = 1;
                    edge[1] = length;
                    if (start[1] + edge[1] > type->dim_sizes[1])
                    {
                        coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading for HDF4 GRImage requires "
                                       "offset (%ld) and length (%ld) to represent a hyperslab (range [%ld,%ld] "
                                       "exceeds length of dimension #1 (%ld)))", offset, length, (long)start[1],
                                       (long)start[1] + edge[1] - 1, type->dim_sizes[1]);
                        return -1;
                    }
                }
                else
                {
                    if (length % type->dim_sizes[1] != 0)
                    {
                        coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading for HDF4 GRImage requires "
                                       "length (%ld) to be a multiple of the subdimension size (%ld)", length,
                                       type->dim_sizes[1]);
                        return -1;
                    }
                    if (offset % type->dim_sizes[1] != 0)
                    {
                        coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading for HDF4 GRImage requires "
                                       " offset (%ld) to be a multiple of the subdimension size (%ld)", offset,
                                       type->dim_sizes[1]);
                        return -1;
                    }
                    start[0] = offset / type->dim_sizes[1];
                    start[1] = 0;
                    edge[0] = length / type->dim_sizes[1];
                    edge[1] = type->dim_sizes[1];
                    if (start[0] + edge[0] > type->dim_sizes[0])
                    {
                        coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading for HDF4 GRImage requires "
                                       "offset (%ld) and length (%ld) to represent a hyperslab (range [%ld,%ld] "
                                       "exceeds length of dimension #0 (%ld)))", offset, length, (long)start[0],
                                       (long)start[0] + edge[0] - 1, type->dim_sizes[0]);
                        return -1;
                    }
                }
                if (GRreadimage(type->ri_id, start, stride, edge, dst) != 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
            }
            break;
        case tag_hdf4_SDS:
            {
                coda_hdf4_SDS *type;
                long block_size = 1;

                type = (coda_hdf4_SDS *)cursor->stack[cursor->n - 1].type;

                /* determine hyperslab start/edge */
                if (type->rank == 0)
                {
                    coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading not allowed for zero "
                                   "dimensional HDF4 SDS");
                    return -1;
                }
                for (i = type->rank - 1; i >= 0; i--)
                {
                    if (length <= block_size * type->dimsizes[i])
                    {
                        if (length % block_size != 0)
                        {
                            coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading for HDF4 SDS requires "
                                           "length (%ld) to be a multiple of the subdimension size (%ld)", length,
                                           block_size);
                            return -1;
                        }
                        start[i] = (offset / block_size) % type->dimsizes[i];
                        edge[i] = length / block_size;
                        break;
                    }
                    start[i] = 0;
                    edge[i] = type->dimsizes[i];
                    block_size *= type->dimsizes[i];
                }
                if (offset % block_size != 0)
                {
                    coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading for HDF4 SDS requires offset "
                                   "(%ld) to be a multiple of the subdimension size (%ld)", offset, block_size);
                    return -1;
                }
                if (start[i] + edge[i] > type->dimsizes[i])
                {
                    coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading for HDF4 SDS requires offset "
                                   "(%ld) and length (%ld) to represent a hyperslab (range [%ld,%ld] exceeds length "
                                   "of dimension #%d (%ld)))", offset, length, (long)start[i],
                                   (long)start[i] + edge[i] - 1, i, type->dimsizes[i]);
                    return -1;
                }
                while (i > 0)
                {
                    block_size *= type->dimsizes[i];
                    i--;
                    start[i] = (offset / block_size) % type->dimsizes[i];
                    edge[i] = 1;
                }

                if (SDreaddata(type->sds_id, start, NULL, edge, dst) != 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
            }
            break;
        case tag_hdf4_Vdata_field:
            coda_set_error(CODA_ERROR_INVALID_ARGUMENT, "partial array reading is not supported for HDF4 Vdata");
            return -1;
        default:
            assert(0);
            exit(1);
    }

    return 0;
}
Example #3
0
static int read_basic_type(const coda_cursor *cursor, void *dst)
{
    int32 start[MAX_HDF4_VAR_DIMS];
    int32 stride[MAX_HDF4_VAR_DIMS];
    int32 edge[MAX_HDF4_VAR_DIMS];
    long index;
    long i;

    index = cursor->stack[cursor->n - 1].index;

    assert(cursor->n > 1);
    switch (((coda_hdf4_type *)cursor->stack[cursor->n - 2].type)->tag)
    {
        case tag_hdf4_basic_type_array:
            {
                coda_cursor array_cursor;
                char *buffer;
                int native_type_size;
                long num_elements;

                /* we first read the whole array and then return only the requested element */

                array_cursor = *cursor;
                array_cursor.n--;

                if (coda_cursor_get_num_elements(&array_cursor, &num_elements) != 0)
                {
                    return -1;
                }
                assert(index < num_elements);
                native_type_size =
                    get_native_type_size(((coda_hdf4_type *)cursor->stack[cursor->n - 1].type)->definition->read_type);
                buffer = malloc(num_elements * native_type_size);
                if (buffer == NULL)
                {
                    coda_set_error(CODA_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)",
                                   (long)(num_elements * native_type_size), __FILE__, __LINE__);
                    return -1;
                }

                if (read_attribute(&array_cursor, buffer, -1) != 0)
                {
                    free(buffer);
                    return -1;
                }

                memcpy(dst, &buffer[index * native_type_size], native_type_size);
                free(buffer);
            }
            break;
        case tag_hdf4_attributes:
        case tag_hdf4_file_attributes:
            if (read_attribute(cursor, dst, -1) != 0)
            {
                return -1;
            }
            break;
        case tag_hdf4_GRImage:
            {
                coda_hdf4_GRImage *type;

                stride[0] = 1;
                stride[1] = 1;
                edge[0] = 1;
                edge[1] = 1;
                type = (coda_hdf4_GRImage *)cursor->stack[cursor->n - 2].type;
                if (type->ncomp != 1)
                {
                    uint8 *buffer;
                    int component_size;
                    int component_index;

                    component_size = get_native_type_size(type->basic_type->definition->read_type);

                    /* HDF4 does not allow reading a single component of a GRImage, so we have to first read all
                     * components and then return only the data item that was requested */
                    buffer = malloc(component_size * type->ncomp);
                    if (buffer == NULL)
                    {
                        coda_set_error(CODA_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)",
                                       (long)(component_size * type->ncomp), __FILE__, __LINE__);
                        return -1;
                    }
                    component_index = index % type->ncomp;
                    index /= type->ncomp;
                    /* For GRImage data the first dimension is the fastest running */
                    start[0] = index % type->dim_sizes[0];
                    start[1] = index / type->dim_sizes[0];
                    if (GRreadimage(type->ri_id, start, stride, edge, buffer) != 0)
                    {
                        coda_set_error(CODA_ERROR_HDF4, NULL);
                        free(buffer);
                        return -1;
                    }
                    memcpy(dst, &buffer[component_index * component_size], component_size);
                    free(buffer);
                }
                else
                {
                    /* For GRImage data the first dimension is the fastest running */
                    start[0] = index % type->dim_sizes[0];
                    start[1] = index / type->dim_sizes[0];
                    if (GRreadimage(type->ri_id, start, stride, edge, dst) != 0)
                    {
                        coda_set_error(CODA_ERROR_HDF4, NULL);
                        return -1;
                    }
                }
            }
            break;
        case tag_hdf4_SDS:
            {
                coda_hdf4_SDS *type;

                type = (coda_hdf4_SDS *)cursor->stack[cursor->n - 2].type;
                if (type->rank == 0)
                {
                    start[0] = 0;
                    edge[1] = 1;
                }
                else
                {
                    for (i = type->rank - 1; i >= 0; i--)
                    {
                        start[i] = index % type->dimsizes[i];
                        index /= type->dimsizes[i];
                        edge[i] = 1;
                    }
                }
                if (SDreaddata(type->sds_id, start, NULL, edge, dst) != 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
            }
            break;
        case tag_hdf4_Vdata_field:
            {
                coda_hdf4_Vdata *type;
                coda_hdf4_Vdata_field *field_type;
                int record_pos;
                int order_pos;

                assert(cursor->n > 2);
                type = (coda_hdf4_Vdata *)cursor->stack[cursor->n - 3].type;
                field_type = (coda_hdf4_Vdata_field *)cursor->stack[cursor->n - 2].type;
                order_pos = index % field_type->order;
                record_pos = index / field_type->order;
                if (VSseek(type->vdata_id, record_pos) < 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
                if (VSsetfields(type->vdata_id, field_type->field_name) != 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
                if (field_type->order > 1)
                {
                    /* HDF4 does not allow reading part of a vdata field, so we have to first read the full field and
                     * then return only the data item that was requested */
                    uint8 *buffer;
                    int element_size;
                    int size;

                    size = VSsizeof(type->vdata_id, field_type->field_name);
                    if (size < 0)
                    {
                        coda_set_error(CODA_ERROR_HDF4, NULL);
                        return -1;
                    }
                    buffer = malloc(size);
                    if (buffer == NULL)
                    {
                        coda_set_error(CODA_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)",
                                       (long)size, __FILE__, __LINE__);
                        return -1;
                    }
                    if (VSread(type->vdata_id, buffer, 1, FULL_INTERLACE) < 0)
                    {
                        coda_set_error(CODA_ERROR_HDF4, NULL);
                        free(buffer);
                        return -1;
                    }
                    /* the size of a field element is the field size divided by the order of the field */
                    element_size = size / field_type->order;
                    memcpy(dst, &buffer[order_pos * element_size], element_size);
                    free(buffer);
                }
                else
                {
                    if (VSread(type->vdata_id, (uint8 *)dst, 1, FULL_INTERLACE) < 0)
                    {
                        coda_set_error(CODA_ERROR_HDF4, NULL);
                        return -1;
                    }
                }
            }
            break;
        default:
            assert(0);
            exit(1);
    }

    return 0;
}
Example #4
0
static int read_array(const coda_cursor *cursor, void *dst)
{
    int32 start[MAX_HDF4_VAR_DIMS];
    int32 stride[MAX_HDF4_VAR_DIMS];
    int32 edge[MAX_HDF4_VAR_DIMS];
    long num_elements;
    long i;

    if (coda_hdf4_cursor_get_num_elements(cursor, &num_elements) != 0)
    {
        return -1;
    }
    if (num_elements <= 0)
    {
        /* no data to be read */
        return 0;
    }

    switch (((coda_hdf4_type *)cursor->stack[cursor->n - 1].type)->tag)
    {
        case tag_hdf4_basic_type_array:
            if (read_attribute(cursor, dst, -1) != 0)
            {
                return -1;
            }
            break;
        case tag_hdf4_GRImage:
            {
                coda_hdf4_GRImage *type;

                type = (coda_hdf4_GRImage *)cursor->stack[cursor->n - 1].type;
                start[0] = 0;
                start[1] = 0;
                stride[0] = 1;
                stride[1] = 1;
                edge[0] = type->dim_sizes[0];
                edge[1] = type->dim_sizes[1];
                if (GRreadimage(type->ri_id, start, stride, edge, dst) != 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
            }
            break;
        case tag_hdf4_SDS:
            {
                coda_hdf4_SDS *type;

                type = (coda_hdf4_SDS *)cursor->stack[cursor->n - 1].type;
                if (type->rank == 0)
                {
                    start[0] = 0;
                    edge[0] = 1;
                }
                else
                {
                    for (i = 0; i < type->rank; i++)
                    {
                        start[i] = 0;
                        edge[i] = type->dimsizes[i];
                    }
                }
                if (SDreaddata(type->sds_id, start, NULL, edge, dst) != 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
            }
            break;
        case tag_hdf4_Vdata_field:
            {
                coda_hdf4_Vdata *type;
                coda_hdf4_Vdata_field *field_type;

                assert(cursor->n > 1);
                type = (coda_hdf4_Vdata *)cursor->stack[cursor->n - 2].type;
                field_type = (coda_hdf4_Vdata_field *)cursor->stack[cursor->n - 1].type;
                if (VSseek(type->vdata_id, 0) < 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
                if (VSsetfields(type->vdata_id, field_type->field_name) != 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
                if (VSread(type->vdata_id, (uint8 *)dst, field_type->num_records, FULL_INTERLACE) < 0)
                {
                    coda_set_error(CODA_ERROR_HDF4, NULL);
                    return -1;
                }
            }
            break;
        default:
            assert(0);
            exit(1);
    }

    return 0;
}