Пример #1
0
Component_destruct(J2K_USER_DATA * data)
{
    if (data)
    {
        ComponentImpl *impl = (ComponentImpl*) data;
        J2K_FREE(data);
    }
}
Пример #2
0
J2KAPI(void) j2k_Writer_destruct(j2k_Writer **writer)
{
    if (*writer)
    {
        if ((*writer)->iface && (*writer)->data)
            (*writer)->iface->destruct((*writer)->data);
        J2K_FREE(*writer);
        *writer = NULL;
    }
}
Пример #3
0
j2k_Container_destruct(j2k_Container **container)
{
    if (*container)
    {
        if ((*container)->iface && (*container)->data)
            (*container)->iface->destruct((*container)->data);
        J2K_FREE(*container);
        *container = NULL;
    }
}
Пример #4
0
j2k_Component_destruct(j2k_Component **component)
{
    if (*component)
    {
        if ((*component)->iface && (*component)->data)
            (*component)->iface->destruct((*component)->data);
        J2K_FREE(*component);
        *component = NULL;
    }
}
Пример #5
0
OpenJPEGWriter_destruct(J2K_USER_DATA * data)
{
    if (data)
    {
        OpenJPEGWriterImpl* const impl = (OpenJPEGWriterImpl*) data;
        OpenJPEG_cleanup(&impl->stream, &impl->codec, &impl->image);
        nrt_IOInterface_destruct(&impl->compressed);
        J2K_FREE(data);
    }
}
Пример #6
0
OpenJPEGReader_destruct(J2K_USER_DATA * data)
{
    if (data)
    {
        OpenJPEGReaderImpl* const impl = (OpenJPEGReaderImpl*) data;
        if (impl->io && impl->ownIO)
        {
            nrt_IOInterface_destruct(&impl->io);
            impl->io = NULL;
        }
        if(impl->container)
        {
            j2k_Container_destruct(&impl->container);
            impl->container = NULL;
        }
        J2K_FREE(data);
    }
}
Пример #7
0
Container_destruct(J2K_USER_DATA * data)
{
    if (data)
    {
        ContainerImpl *impl = (ContainerImpl*) data;
        if (impl->components)
        {
            nrt_Uint32 i = 0;
            for(; i < impl->nComponents; ++i)
            {
                j2k_Component *c = impl->components[i];
                if (c)
                    j2k_Component_destruct(&c);
            }
            impl->components = NULL;
        }
        J2K_FREE(data);
    }
}
Пример #8
0
J2K_BOOL readFile(const char* filename, char **buf, nrt_Uint64 *bufSize,
                  nrt_Error *error)
{
    J2K_BOOL rc = J2K_TRUE;
    nrt_IOInterface *io = NULL;

    if (!(io = nrt_IOHandleAdapter_open(filename, NRT_ACCESS_READONLY,
                                        NRT_OPEN_EXISTING, error)))
        goto CATCH_ERROR;

    *bufSize = nrt_IOInterface_getSize(io, error);
    if (!(*buf = (char*)J2K_MALLOC(*bufSize)))
    {
        nrt_Error_init(error, NRT_STRERROR(NRT_ERRNO), NRT_CTXT, NRT_ERR_MEMORY);
        goto CATCH_ERROR;
    }

    if (!nrt_IOInterface_read(io, *buf, *bufSize, error))
    {
        goto CATCH_ERROR;
    }

    goto CLEANUP;

    CATCH_ERROR:
    {
        rc = J2K_FALSE;
        if (*buf)
            J2K_FREE(*buf);
        *buf = NULL;
    }
    CLEANUP:
    {
        if (io)
            nrt_IOInterface_destruct(&io);
    }
    return rc;
}
Пример #9
0
int main(int argc, char **argv)
{
    int rc = 0;
    int argIt = 0;
    char *inName = NULL, *outName = NULL;
    nrt_Error error;
    j2k_Component *component = NULL;
    j2k_Container *container = NULL;
    j2k_Writer *writer = NULL;
    j2k_WriterOptions options;
    char *buf = NULL;
    nrt_Uint64 bufSize;
    nrt_IOInterface *outIO = NULL;
    nrt_Uint32 width, height, precision, tileWidth, tileHeight;

    for (argIt = 1; argIt < argc; ++argIt)
    {
        if (!inName)
        {
            inName = argv[argIt];
        }
        else if (!outName)
        {
            outName = argv[argIt];
        }
    }

    /* hardcoded for now... */
    width = 128;
    height = 128;
    precision = 8;
    tileWidth = width;
    tileHeight = height;

    if (!inName || !outName)
    {
        nrt_Error_initf(&error, NRT_CTXT, NRT_ERR_INVALID_OBJECT,
                        "Usage: %s <raw-input> <output-j2k>", argv[0]);
        goto CATCH_ERROR;
    }

    if (!(component = j2k_Component_construct(width, height, precision,
                                              0, 0, 0, 1, 1, &error)))
    {
        goto CATCH_ERROR;
    }

    if (!(container = j2k_Container_construct(width,
                                              height,
                                              1,
                                              &component,
                                              tileWidth,
                                              tileHeight,
                                              J2K_TYPE_MONO,
                                              &error)))
    {
        goto CATCH_ERROR;
    }

    memset(&options, 0, sizeof(j2k_WriterOptions));
    /* TODO set some options here */

    if (!(writer = j2k_Writer_construct(container, &options, &error)))
    {
        goto CATCH_ERROR;
    }

    if (!readFile(inName, &buf, &bufSize, &error))
    {
        goto CATCH_ERROR;
    }

    if (!j2k_Writer_setTile(writer, 0, 0, (nrt_Uint8*)buf,
                            (nrt_Uint32)bufSize, &error))
    {
        goto CATCH_ERROR;
    }

    if (!(outIO = nrt_IOHandleAdapter_open(outName, NRT_ACCESS_WRITEONLY,
                                           NRT_CREATE, &error)))
        goto CATCH_ERROR;

    if (!j2k_Writer_write(writer, outIO, &error))
        goto CATCH_ERROR;

    goto CLEANUP;

    CATCH_ERROR:
    {
        nrt_Error_print(&error, stdout, "Exiting...");
        rc = 1;
    }
    CLEANUP:
    {
        if (container)
            j2k_Container_destruct(&container);
        if (writer)
            j2k_Writer_destruct(&writer);
        if (buf)
            J2K_FREE(buf);
        if (outIO)
            nrt_IOInterface_destruct(&outIO);
    }
    return rc;

}
Пример #10
0
OpenJPEGWriter_setTile(J2K_USER_DATA *data, nrt_Uint32 tileX, nrt_Uint32 tileY,
                       const nrt_Uint8 *buf, nrt_Uint32 tileSize,
                       nrt_Error *error)
{
    OpenJPEGWriterImpl *impl = (OpenJPEGWriterImpl*) data;
    NRT_BOOL rc = NRT_SUCCESS;
    nrt_Uint32 xTiles, yTiles, tileIndex, width, height, tileWidth, tileHeight;
    nrt_Uint32 thisTileWidth, thisTileHeight, thisTileSize, nComponents, nBytes;
    nrt_Uint8* newTileBuf = NULL;

    xTiles = j2k_Container_getTilesX(impl->container, error);
    yTiles = j2k_Container_getTilesY(impl->container, error);
    width  = j2k_Container_getWidth(impl->container, error);
    height = j2k_Container_getHeight(impl->container, error);
    tileWidth  = j2k_Container_getTileWidth(impl->container, error);
    tileHeight = j2k_Container_getTileHeight(impl->container, error);
    nComponents = j2k_Container_getNumComponents(impl->container, error);
    nBytes = (j2k_Container_getPrecision(impl->container, error) - 1) / 8 + 1;
    tileIndex = tileY * xTiles + tileX;

    memset(error->message, 0, NRT_MAX_EMESSAGE);
    if(!opj_set_error_handler(impl->codec,
                              OpenJPEG_errorHandler,
                              error))
    {
        nrt_Error_init(error, "Unable to set OpenJPEG error handler", NRT_CTXT,
                       NRT_ERR_UNK);
        goto CATCH_ERROR;
    }

    /* Check for edge case where we may have partial tile */
    thisTileWidth = tileWidth;
    thisTileHeight = tileHeight;
    if (tileX == xTiles - 1 && width % tileWidth != 0)
        thisTileWidth = width % tileWidth;
    if (tileY == yTiles - 1 && height % tileHeight != 0)
        thisTileHeight = height % tileHeight;

    thisTileSize = thisTileWidth * thisTileHeight * nComponents * nBytes;
    if(thisTileSize != tileSize)
        tileSize = thisTileSize;

    if(thisTileWidth < tileWidth)
    {
        /* TODO: The current approach below only works for single band
         *       imagery.  For RGB data, I believe it is stored as all
         *       red, then all green, then all blue, so we would need
         *       a temp buffer rather than reusing the current buffer.
         */
        if (nComponents != 1)
        {
            nrt_Error_init(
                error,
                "Partial tile width not implemented for multi-band",
                NRT_CTXT, NRT_ERR_UNK);
            goto CATCH_ERROR;
        }
        
        /* We have a tile that is wider than it "should" be
         * Need to create smaller buffer to pass to write function
         */
        {
            OPJ_UINT32 ii;
            size_t srcOffset = 0;
            size_t destOffset = 0;
            const size_t srcStride = tileWidth * nBytes;
            const size_t destStride = thisTileWidth * nBytes;
            
            newTileBuf = (nrt_Uint8*) J2K_MALLOC(thisTileSize);
            if(!newTileBuf)
            {
                nrt_Error_init(error, NRT_STRERROR(NRT_ERRNO), NRT_CTXT, NRT_ERR_MEMORY);
                goto CATCH_ERROR;
            }
            
            for(ii = 0; ii < thisTileHeight; ++ii, srcOffset += srcStride, 
                    destOffset += destStride)
                memcpy(newTileBuf + destOffset, buf + srcOffset, destStride);

            buf = newTileBuf;
        }
    }

    if (!opj_write_tile(impl->codec,
                        tileIndex,
                        (OPJ_BYTE* )buf,
                        tileSize,
                        impl->stream))
    {
        nrt_Error ioError;
        const nrt_Off currentPos = nrt_IOInterface_tell(impl->compressed, &ioError);
        const nrt_Off ioSize = nrt_IOInterface_getSize(impl->compressed, &ioError);
        if (NRT_IO_SUCCESS(currentPos) &&
            NRT_IO_SUCCESS(ioSize) &&
            currentPos + OPENJPEG_STREAM_SIZE >= ioSize)
        {
            /* The write failed because implStreamWrite() failed because
             * nrt_IOInterface_write() failed because we didn't have enough
             * room left in the buffer that we copy to prior to flushing out
             * to disk in OpenJPEGWriter_write().  The buffer is sized to the
             * uncompressed image size, so this only occurs if the compressed
             * image is actually larger than the uncompressed size.
             * TODO: Handle resizing the buffer on the fly when this occurs
             * inside implStreamWrite().  Long-term if we're able to thread
             * per tile, we won't have to reallocate nearly as much.
             */
            nrt_Error_init(error,
                           "Error writing tile: Compressed image is larger "
                            "than uncompressed image",
                            NRT_CTXT,
                            NRT_ERR_INVALID_OBJECT);
        }

        /*nrt_Error_init(error, "Error writing tile", NRT_CTXT,
          NRT_ERR_INVALID_OBJECT);*/
        goto CATCH_ERROR;
    }

    goto CLEANUP;

    CATCH_ERROR:
    {
        rc = NRT_FAILURE;
    }

    CLEANUP:
    {
        if(newTileBuf)
            J2K_FREE(newTileBuf);
    }

    return rc;
}
Пример #11
0
J2KPRIV( NRT_BOOL) OpenJPEG_initImage(OpenJPEGWriterImpl *impl,
                                      j2k_WriterOptions *writerOps,
                                      nrt_Error *error)
{
    NRT_BOOL rc = NRT_SUCCESS;
    nrt_Uint32 i, nComponents, height, width, tileHeight, tileWidth;
    nrt_Uint32 nBytes;
    j2k_Component *component = NULL;
    size_t uncompressedSize;
    int imageType;
    opj_cparameters_t encoderParams;
    opj_image_cmptparm_t *cmptParams;
    OPJ_COLOR_SPACE colorSpace;

    nComponents = j2k_Container_getNumComponents(impl->container, error);
    width = j2k_Container_getWidth(impl->container, error);
    height = j2k_Container_getHeight(impl->container, error);
    tileWidth = j2k_Container_getTileWidth(impl->container, error);
    tileHeight = j2k_Container_getTileHeight(impl->container, error);
    imageType = j2k_Container_getImageType(impl->container, error);

    /* Set up the encoder parameters.  This defaults to lossless. */
    /* TODO allow overrides somehow? */
    opj_set_default_encoder_parameters(&encoderParams);

    /* For now we are enforcing lossless compression.  If we have a better
     * way to allow overrides in the future, uncomment out the tcp_rates logic
     * below (tcp_rates[0] == 0 via opj_set_default_encoder_parameters()).
     * Also consider setting encoderParams.irreversible = 1; to use the
     * lossy DWT 9-7 instead of the reversible 5-3.
     */

    /*if (writerOps && writerOps->compressionRatio > 0.0001)
        encoderParams.tcp_rates[0] = 1.0 / writerOps->compressionRatio;
    else
        encoderParams.tcp_rates[0] = 4.0;
    */

    /* TODO: These two lines should not be necessary when using lossless
     *       encoding but appear to be needed (at least in OpenJPEG 2.0) -
     *       otherwise we get a seg fault.
     *       The sample opj_compress.c is doing the same thing with a comment
     *       indicating that it's a bug. */
    ++encoderParams.tcp_numlayers;
    encoderParams.cp_disto_alloc = 1;

    if (writerOps && writerOps->numResolutions > 0)
    {
        encoderParams.numresolution = writerOps->numResolutions;
        /* Note, if this isn't set right (see below) it will error out */
    }
    else
    {
        /* 
           OpenJPEG defaults this to 6, but that causes the compressor 
           to fail if the tile sizes are less than 2^6.  So we adjust this
           down if necessary.
        */
        const double logTwo = log(2);
        const OPJ_UINT32 minX = (OPJ_UINT32)floor(log(tileWidth) / logTwo);
        const OPJ_UINT32 minY = (OPJ_UINT32)floor(log(tileHeight) / logTwo);
        const OPJ_UINT32 minXY = (minX < minY) ? minX : minY;
        if (minXY < encoderParams.numresolution)
        {
            encoderParams.numresolution = minXY;
        }
    }

    /* Turn on tiling */
    encoderParams.tile_size_on = 1;
    encoderParams.cp_tx0 = 0;
    encoderParams.cp_ty0 = 0;
    encoderParams.cp_tdx = tileWidth;
    encoderParams.cp_tdy = tileHeight;

    if (!(cmptParams = (opj_image_cmptparm_t*)J2K_MALLOC(sizeof(
            opj_image_cmptparm_t) * nComponents)))
    {
        nrt_Error_init(error, NRT_STRERROR(NRT_ERRNO), NRT_CTXT,
                       NRT_ERR_MEMORY);
        goto CATCH_ERROR;
    }
    memset(cmptParams, 0, sizeof(opj_image_cmptparm_t) * nComponents);

    for(i = 0; i < nComponents; ++i)
    {
        component = j2k_Container_getComponent(impl->container, i, error);
        cmptParams[i].w = j2k_Component_getWidth(component, error);
        cmptParams[i].h = j2k_Component_getHeight(component, error);
        cmptParams[i].prec = j2k_Component_getPrecision(component, error);
        cmptParams[i].x0 = j2k_Component_getOffsetX(component, error);
        cmptParams[i].y0 = j2k_Component_getOffsetY(component, error);
        cmptParams[i].dx = j2k_Component_getSeparationX(component, error);
        cmptParams[i].dy = j2k_Component_getSeparationY(component, error);
        cmptParams[i].sgnd = j2k_Component_isSigned(component, error);
    }

    nBytes = (j2k_Container_getPrecision(impl->container, error) - 1) / 8 + 1;
    uncompressedSize = width * height * nComponents * nBytes;

    /* this is not ideal, but there is really no other way */
    if (!(impl->compressedBuf = (char*)J2K_MALLOC(uncompressedSize)))
    {
        nrt_Error_init(error, NRT_STRERROR(NRT_ERRNO), NRT_CTXT,
                       NRT_ERR_MEMORY);
        goto CATCH_ERROR;
    }
    if (!(impl->compressed = nrt_BufferAdapter_construct(impl->compressedBuf,
                                                         uncompressedSize, 1,
                                                         error)))
    {
        goto CATCH_ERROR;
    }

    if (!(impl->stream = OpenJPEG_createIO(impl->compressed, &impl->userData,
                                           0, 0, error)))
    {
        goto CATCH_ERROR;
    }


    switch(imageType)
    {
    case J2K_TYPE_RGB:
        colorSpace = OPJ_CLRSPC_SRGB;
        break;
    default:
        colorSpace = OPJ_CLRSPC_GRAY;
    }

    if (!(impl->codec = opj_create_compress(OPJ_CODEC_J2K)))
    {
        nrt_Error_init(error, "Error creating OpenJPEG codec", NRT_CTXT,
                       NRT_ERR_INVALID_OBJECT);
        goto CATCH_ERROR;
    }
    if (!(impl->image = opj_image_tile_create(nComponents, cmptParams,
                                              colorSpace)))
    {
        nrt_Error_init(error, "Error creating OpenJPEG image", NRT_CTXT,
                       NRT_ERR_INVALID_OBJECT);
        goto CATCH_ERROR;
    }

    /* for some reason we must also explicitly specify these in the image... */
    impl->image->numcomps = nComponents;
    impl->image->x0 = 0;
    impl->image->y0 = 0;
    impl->image->x1 = width;
    impl->image->y1 = height;
    impl->image->color_space = colorSpace;

    memset(error->message, 0, NRT_MAX_EMESSAGE);
    if(!opj_set_error_handler(impl->codec,
                              OpenJPEG_errorHandler,
                              error))
    {
        nrt_Error_init(error, "Unable to set OpenJPEG error handler", NRT_CTXT,
                       NRT_ERR_UNK);
        goto CATCH_ERROR;
    }

    if (!opj_setup_encoder(impl->codec, &encoderParams, impl->image))
    {
        /*nrt_Error_init(error, "Error setting up OpenJPEG decoder", NRT_CTXT,
          NRT_ERR_INVALID_OBJECT);*/
        goto CATCH_ERROR;
    }

    if (!opj_start_compress(impl->codec, impl->image, impl->stream))
    {
        /*nrt_Error_init(error, "Error starting OpenJPEG compression", NRT_CTXT,
          NRT_ERR_INVALID_OBJECT);*/
        goto CATCH_ERROR;
    }

    goto CLEANUP;

    CATCH_ERROR:
    {
        rc = NRT_FAILURE;
    }

    CLEANUP:
    {
        if (cmptParams)
            J2K_FREE(cmptParams);
    }

    return rc;
}