J2KAPI(nrt_Uint32) j2k_Container_getHeight(j2k_Container *container, nrt_Error *error) { nrt_Uint32 nComponents, i, height, cHeight; nComponents = j2k_Container_getNumComponents(container, error); height = 0; for(i = 0; i < nComponents; ++i) { j2k_Component *c = j2k_Container_getComponent(container, i, error); cHeight = j2k_Component_getHeight(c, error); if (cHeight > height) height = cHeight; } return height; }
int main(int argc, char **argv) { int rc = 0; int argIt = 0, i = 0, num = 0, dump = 0; char *fname = NULL; nrt_Error error; nrt_IOInterface *io = NULL; nitf_Reader *reader = NULL; nitf_Record *record = NULL; nrt_Uint8 *buf = NULL; for (argIt = 1; argIt < argc; ++argIt) { if (strcmp(argv[argIt], "--dump") == 0) dump = 1; else if (!fname) { fname = argv[argIt]; } } if (!fname) { nrt_Error_init(&error, "Usage: [--x0 --y0 --x1 --y1] <j2k-file>", NRT_CTXT, NRT_ERR_INVALID_OBJECT); goto CATCH_ERROR; } if (nitf_Reader_getNITFVersion(fname) == NITF_VER_UNKNOWN) { nrt_Error_init(&error, "This file does not appear to be a valid NITF", NRT_CTXT, NRT_ERR_INVALID_OBJECT); goto CATCH_ERROR; } if (!(io = nrt_IOHandleAdapter_open(fname, NRT_ACCESS_READONLY, NRT_OPEN_EXISTING, &error))) goto CATCH_ERROR; if (!(reader = nitf_Reader_construct(&error))) goto CATCH_ERROR; if (!(record = nitf_Reader_readIO(reader, io, &error))) goto CATCH_ERROR; num = nitf_Record_getNumImages(record, &error); if (num > 0) { nitf_ListIterator iter = nitf_List_begin(record->images); nitf_ListIterator end = nitf_List_end(record->images); for (i = 0; nitf_ListIterator_notEqualTo(&iter, &end); ++i) { nitf_ImageSegment *segment = (nitf_ImageSegment *) nitf_ListIterator_get(&iter); nitf_ImageSubheader *subheader = segment->subheader; if (strcmp(subheader->imageCompression->raw, "C8") == 0) { j2k_Reader *j2kReader = NULL; j2k_Container *container = NULL; nrt_Uint32 cmpIt, nComponents; printf("Image %d contains J2K compressed data\n", (i + 1)); printf("Offset: %d\n", segment->imageOffset); if (!nrt_IOInterface_seek(io, segment->imageOffset, NRT_SEEK_SET, &error)) goto CATCH_ERROR; if (!(j2kReader = j2k_Reader_openIO(io, &error))) goto CATCH_ERROR; if (!(container = j2k_Reader_getContainer(j2kReader, &error))) goto CATCH_ERROR; printf("grid width:\t%d\n", j2k_Container_getGridWidth(container, &error)); printf("grid height:\t%d\n", j2k_Container_getGridHeight(container, &error)); printf("tile width:\t%d\n", j2k_Container_getTileWidth(container, &error)); printf("tile height:\t%d\n", j2k_Container_getTileHeight(container, &error)); printf("x tiles:\t%d\n", j2k_Container_getTilesX(container, &error)); printf("y tiles:\t%d\n", j2k_Container_getTilesY(container, &error)); printf("image type:\t%d\n", j2k_Container_getImageType(container, &error)); nComponents = j2k_Container_getNumComponents(container, &error); printf("components:\t%d\n", nComponents); for(cmpIt = 0; cmpIt < nComponents; ++cmpIt) { j2k_Component* c = j2k_Container_getComponent(container, cmpIt, &error); printf("===component %d===\n", (cmpIt + 1)); printf("width:\t\t%d\n", j2k_Component_getWidth(c, &error)); printf("height:\t\t%d\n", j2k_Component_getHeight(c, &error)); printf("precision:\t%d\n", j2k_Component_getPrecision(c, &error)); printf("x0:\t\t%d\n", j2k_Component_getOffsetX(c, &error)); printf("y0:\t\t%d\n", j2k_Component_getOffsetY(c, &error)); printf("x separation:\t%d\n", j2k_Component_getSeparationX(c, &error)); printf("y separation:\t%d\n", j2k_Component_getSeparationY(c, &error)); printf("signed:\t\t%d\n", j2k_Component_isSigned(c, &error)); } if (dump) { char namePrefix[NRT_MAX_PATH]; nrt_Uint32 width, height; nrt_Uint64 bufSize; if (buf) { NRT_FREE(buf); buf = NULL; } width = j2k_Container_getWidth(container, &error); height = j2k_Container_getWidth(container, &error); if ((bufSize = j2k_Reader_readRegion(j2kReader, 0, 0, width, height, &buf, &error)) == 0) { goto CATCH_ERROR; } NRT_SNPRINTF(namePrefix, NRT_MAX_PATH, "image-%d", (i + 1)); if (!writeFile(0, 0, width, height, buf, bufSize, namePrefix, &error)) { goto CATCH_ERROR; } } } nitf_ListIterator_increment(&iter); } } goto CLEANUP; CATCH_ERROR: { nrt_Error_print(&error, stdout, "Exiting..."); rc = 1; } CLEANUP: { if (reader) nitf_Reader_destruct(&reader); if (record) nitf_Record_destruct(&record); if (io) nrt_IOInterface_destruct(&io); } return rc; }
int main(int argc, char **argv) { int rc = 0; int argIt; nrt_Uint32 cmpIt, nComponents; nrt_Error error; j2k_Container *container = NULL; j2k_Reader *reader = NULL; char *fname = NULL; for (argIt = 1; argIt < argc; ++argIt) { if (!fname) { fname = argv[argIt]; } } if (!fname) { nrt_Error_init(&error, "Usage: [options] <j2k-file>", NRT_CTXT, NRT_ERR_INVALID_OBJECT); goto CATCH_ERROR; } if (!(reader = j2k_Reader_open(fname, &error))) goto CATCH_ERROR; if (!(container = j2k_Reader_getContainer(reader, &error))) goto CATCH_ERROR; printf("grid width:\t%d\n", j2k_Container_getGridWidth(container, &error)); printf("grid height:\t%d\n", j2k_Container_getGridHeight(container, &error)); printf("tile width:\t%d\n", j2k_Container_getTileWidth(container, &error)); printf("tile height:\t%d\n", j2k_Container_getTileHeight(container, &error)); printf("x tiles:\t%d\n", j2k_Container_getTilesX(container, &error)); printf("y tiles:\t%d\n", j2k_Container_getTilesY(container, &error)); printf("image type:\t%d\n", j2k_Container_getImageType(container, &error)); nComponents = j2k_Container_getNumComponents(container, &error); printf("components:\t%d\n", nComponents); for(cmpIt = 0; cmpIt < nComponents; ++cmpIt) { j2k_Component* c = j2k_Container_getComponent(container, cmpIt, &error); printf("===component %d===\n", (cmpIt + 1)); printf("width:\t\t%d\n", j2k_Component_getWidth(c, &error)); printf("height:\t\t%d\n", j2k_Component_getHeight(c, &error)); printf("precision:\t%d\n", j2k_Component_getPrecision(c, &error)); printf("x0:\t\t%d\n", j2k_Component_getOffsetX(c, &error)); printf("y0:\t\t%d\n", j2k_Component_getOffsetY(c, &error)); printf("x separation:\t%d\n", j2k_Component_getSeparationX(c, &error)); printf("y separation:\t%d\n", j2k_Component_getSeparationY(c, &error)); printf("signed:\t\t%d\n", j2k_Component_isSigned(c, &error)); } goto CLEANUP; CATCH_ERROR: { nrt_Error_print(&error, stdout, "Exiting..."); rc = 1; } CLEANUP: { if (reader) j2k_Reader_destruct(&reader); } return rc; }
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; }