- int subsampling_dx = parameters->subsampling_dx;
- int subsampling_dy = parameters->subsampling_dy;
- TIFF *tif;
- tdata_t buf;
- tstrip_t strip;
- tsize_t strip_size;
- int j, currentPlane, numcomps = 0, w, h;
- OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_UNKNOWN;
- opj_image_cmptparm_t cmptparm[4]; /* RGBA */
- opj_image_t *image = NULL;
- int has_alpha = 0;
- unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
- unsigned int tiWidth, tiHeight;
- OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
- tif_Xto32s cvtTifTo32s = NULL;
- convert_32s_CXPX cvtCxToPx = NULL;
- OPJ_INT32* buffer32s = NULL;
- OPJ_INT32* planes[4];
- OPJ_SIZE_T rowStride;
-
- tif = TIFFOpen(filename, "r");
-
- if(!tif)
- {
- fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename);
- return 0;
- }
- tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0;
- tiWidth = tiHeight = 0;
-
- TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth);
- TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight);
- TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps);
- TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf);
- TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
- TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
- TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
- w= (int)tiWidth;
- h= (int)tiHeight;
-
- if((tiBps > 16U) || ((tiBps != 1U) && (tiBps & 1U))) {
- fprintf(stderr,"tiftoimage: Bits=%d, Only 1, 2, 4, 6, 8, 10, 12, 14 and 16 bits implemented\n",tiBps);
- fprintf(stderr,"\tAborting\n");
- TIFFClose(tif);
- return NULL;
- }
- if(tiPhoto != PHOTOMETRIC_MINISBLACK && tiPhoto != PHOTOMETRIC_RGB) {
- fprintf(stderr,"tiftoimage: Bad color format %d.\n\tOnly RGB(A) and GRAY(A) has been implemented\n",(int) tiPhoto);
- fprintf(stderr,"\tAborting\n");
- TIFFClose(tif);
- return NULL;
- }
-
- switch (tiBps) {
- case 1:
- cvtTifTo32s = tif_1uto32s;
- break;
- case 2:
- cvtTifTo32s = tif_2uto32s;
- break;
- case 4:
- cvtTifTo32s = tif_4uto32s;
- break;
- case 6:
- cvtTifTo32s = tif_6uto32s;
- break;
- case 8:
- cvtTifTo32s = tif_8uto32s;
- break;
- case 10:
- cvtTifTo32s = tif_10uto32s;
- break;
- case 12:
- cvtTifTo32s = tif_12uto32s;
- break;
- case 14:
- cvtTifTo32s = tif_14uto32s;
- break;
- case 16:
- cvtTifTo32s = (tif_Xto32s)tif_16uto32s;
- break;
- default:
- /* never here */
- break;
- }
-
- {/* From: tiff-4.0.x/libtiff/tif_getimage.c : */
- uint16* sampleinfo;
- uint16 extrasamples;
-
- TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
- &extrasamples, &sampleinfo);
-
- if(extrasamples >= 1)
- {
- switch(sampleinfo[0])
- {
- case EXTRASAMPLE_UNSPECIFIED:
- /* Workaround for some images without correct info about alpha channel
- */
- if(tiSpp > 3)
- has_alpha = 1;
- break;
-
- case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */
- case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */
- has_alpha = 1;
- break;
- }
- }
- else /* extrasamples == 0 */
- if(tiSpp == 4 || tiSpp == 2) has_alpha = 1;
- }
-
- /* initialize image components */
- memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
-
- if ((tiPhoto == PHOTOMETRIC_RGB) && (is_cinema) && (tiBps != 12U)) {
- fprintf(stdout,"WARNING:\n"
- "Input image bitdepth is %d bits\n"
- "TIF conversion has automatically rescaled to 12-bits\n"
- "to comply with cinema profiles.\n",
- tiBps);
- } else {
- is_cinema = 0U;
- }
-
- if(tiPhoto == PHOTOMETRIC_RGB) /* RGB(A) */
- {
- numcomps = 3 + has_alpha;
- color_space = OPJ_CLRSPC_SRGB;
- }
- else if (tiPhoto == PHOTOMETRIC_MINISBLACK) /* GRAY(A) */
- {
- numcomps = 1 + has_alpha;
- color_space = OPJ_CLRSPC_GRAY;
- }
-
- switch (numcomps) {
- case 1:
- cvtCxToPx = convert_32s_C1P1;
- break;
- case 2:
- cvtCxToPx = convert_32s_C2P2;
- break;
- case 3:
- cvtCxToPx = convert_32s_C3P3;
- break;
- case 4:
- cvtCxToPx = convert_32s_C4P4;
- break;
- default:
- /* never here */
- break;
- }
- if (tiPC == PLANARCONFIG_SEPARATE) {
- cvtCxToPx = convert_32s_C1P1; /* override */
- tiSpp = 1U; /* consider only one sample per plane */
- }
-
- for(j = 0; j < numcomps; j++)
- {
- cmptparm[j].prec = tiBps;
- cmptparm[j].bpp = tiBps;
- cmptparm[j].dx = (OPJ_UINT32)subsampling_dx;
- cmptparm[j].dy = (OPJ_UINT32)subsampling_dy;
- cmptparm[j].w = (OPJ_UINT32)w;
- cmptparm[j].h = (OPJ_UINT32)h;
- }
-
- image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
- if(!image)
- {
- TIFFClose(tif);
- return NULL;
- }
- /* set image offset and reference grid */
- image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
- image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
- image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 :
- image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
- image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 :
- image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1;
-
- for(j = 0; j < numcomps; j++)
- {
- planes[j] = image->comps[j].data;
- }
- image->comps[numcomps - 1].alpha = (OPJ_UINT16)(1 - (numcomps & 1));
-
- strip_size = TIFFStripSize(tif);
-
- buf = _TIFFmalloc(strip_size);
- if (buf == NULL) {
- TIFFClose(tif);
- opj_image_destroy(image);
- return NULL;
- }
- rowStride = ((OPJ_SIZE_T)w * tiSpp * tiBps + 7U) / 8U;
- buffer32s = malloc((OPJ_SIZE_T)w * tiSpp * sizeof(OPJ_INT32));
- if (buffer32s == NULL) {
- _TIFFfree(buf);
- TIFFClose(tif);
- opj_image_destroy(image);
- return NULL;
- }
-
- strip = 0;
- currentPlane = 0;
- do
- {
- planes[0] = image->comps[currentPlane].data; /* to manage planar data */
- h= (int)tiHeight;
- /* Read the Image components */
- for(; (h > 0) && (strip < TIFFNumberOfStrips(tif)); strip++)
- {
- const OPJ_UINT8 *dat8;
- OPJ_SIZE_T ssize;
-
- ssize = (OPJ_SIZE_T)TIFFReadEncodedStrip(tif, strip, buf, strip_size);
- dat8 = (const OPJ_UINT8*)buf;
-
- while (ssize >= rowStride) {
- cvtTifTo32s(dat8, buffer32s, (OPJ_SIZE_T)w * tiSpp);
- cvtCxToPx(buffer32s, planes, (OPJ_SIZE_T)w);
- planes[0] += w;
- planes[1] += w;
- planes[2] += w;
- planes[3] += w;
- dat8 += rowStride;
- ssize -= rowStride;
- h--;
- }
- }
- currentPlane++;
- } while ((tiPC == PLANARCONFIG_SEPARATE) && (currentPlane < numcomps));
-
- free(buffer32s);
- _TIFFfree(buf);
- TIFFClose(tif);
-
- if (is_cinema) {
- for (j=0; j < numcomps; ++j) {
- scale_component(&(image->comps[j]), 12);
- }
-
- }
- return image;
+ int subsampling_dx = parameters->subsampling_dx;
+ int subsampling_dy = parameters->subsampling_dy;
+ TIFF *tif;
+ tdata_t buf;
+ tstrip_t strip;
+ int64_t strip_size, rowStride, TIFF_MAX;
+ int j, currentPlane, numcomps = 0, w, h;
+ OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_UNKNOWN;
+ opj_image_cmptparm_t cmptparm[4]; /* RGBA */
+ opj_image_t *image = NULL;
+ uint16 tiBps, tiPhoto, tiSf, tiSpp, tiPC;
+ uint32 tiWidth, tiHeight;
+ OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
+ convert_XXx32s_C1R cvtTifTo32s = NULL;
+ convert_32s_CXPX cvtCxToPx = NULL;
+ OPJ_INT32* buffer32s = NULL;
+ OPJ_INT32* planes[4];
+
+ tif = TIFFOpen(filename, "r");
+
+ if (!tif) {
+ fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename);
+ return 0;
+ }
+ tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0;
+ tiWidth = tiHeight = 0;
+
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth);
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight);
+ TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps);
+ TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf);
+ TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
+ TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
+ TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
+ w = (int)tiWidth;
+ h = (int)tiHeight;
+
+ if (tiSpp == 0 || tiSpp > 4) { /* should be 1 ... 4 */
+ fprintf(stderr, "tiftoimage: Bad value for samples per pixel == %d.\n"
+ "\tAborting.\n", tiSpp);
+ TIFFClose(tif);
+ return NULL;
+ }
+ if (tiBps > 16U || tiBps == 0) {
+ fprintf(stderr, "tiftoimage: Bad values for Bits == %d.\n"
+ "\tMax. 16 Bits are allowed here.\n\tAborting.\n", tiBps);
+ TIFFClose(tif);
+ return NULL;
+ }
+ if (tiPhoto != PHOTOMETRIC_MINISBLACK && tiPhoto != PHOTOMETRIC_RGB) {
+ fprintf(stderr,
+ "tiftoimage: Bad color format %d.\n\tOnly RGB(A) and GRAY(A) has been implemented\n\tAborting.\n",
+ (int) tiPhoto);
+ TIFFClose(tif);
+ return NULL;
+ }
+ if (tiWidth == 0 || tiHeight == 0) {
+ fprintf(stderr, "tiftoimage: Bad values for width(%u) "
+ "and/or height(%u)\n\tAborting.\n", tiWidth, tiHeight);
+ TIFFClose(tif);
+ return NULL;
+ }
+ w = (int)tiWidth;
+ h = (int)tiHeight;
+
+ switch (tiBps) {
+ case 1:
+ case 2:
+ case 4:
+ case 6:
+ case 8:
+ cvtTifTo32s = convert_XXu32s_C1R_LUT[tiBps];
+ break;
+ /* others are specific to TIFF */
+ case 3:
+ cvtTifTo32s = tif_3uto32s;
+ break;
+ case 5:
+ cvtTifTo32s = tif_5uto32s;
+ break;
+ case 7:
+ cvtTifTo32s = tif_7uto32s;
+ break;
+ case 9:
+ cvtTifTo32s = tif_9uto32s;
+ break;
+ case 10:
+ cvtTifTo32s = tif_10uto32s;
+ break;
+ case 11:
+ cvtTifTo32s = tif_11uto32s;
+ break;
+ case 12:
+ cvtTifTo32s = tif_12uto32s;
+ break;
+ case 13:
+ cvtTifTo32s = tif_13uto32s;
+ break;
+ case 14:
+ cvtTifTo32s = tif_14uto32s;
+ break;
+ case 15:
+ cvtTifTo32s = tif_15uto32s;
+ break;
+ case 16:
+ cvtTifTo32s = (convert_XXx32s_C1R)tif_16uto32s;
+ break;
+ default:
+ /* never here */
+ break;
+ }
+
+ /* initialize image components */
+ memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
+
+ if ((tiPhoto == PHOTOMETRIC_RGB) && (is_cinema) && (tiBps != 12U)) {
+ fprintf(stdout, "WARNING:\n"
+ "Input image bitdepth is %d bits\n"
+ "TIF conversion has automatically rescaled to 12-bits\n"
+ "to comply with cinema profiles.\n",
+ tiBps);
+ } else {
+ is_cinema = 0U;
+ }
+
+ numcomps = tiSpp;
+ if (tiPhoto == PHOTOMETRIC_RGB) { /* RGB(A) */
+ color_space = OPJ_CLRSPC_SRGB;
+ } else if (tiPhoto == PHOTOMETRIC_MINISBLACK) { /* GRAY(A) */
+ color_space = OPJ_CLRSPC_GRAY;
+ }
+
+ cvtCxToPx = convert_32s_CXPX_LUT[numcomps];
+ if (tiPC == PLANARCONFIG_SEPARATE) {
+ cvtCxToPx = convert_32s_CXPX_LUT[1]; /* override */
+ tiSpp = 1U; /* consider only one sample per plane */
+ }
+
+ for (j = 0; j < numcomps; j++) {
+ cmptparm[j].prec = tiBps;
+ cmptparm[j].bpp = tiBps;
+ cmptparm[j].dx = (OPJ_UINT32)subsampling_dx;
+ cmptparm[j].dy = (OPJ_UINT32)subsampling_dy;
+ cmptparm[j].w = (OPJ_UINT32)w;
+ cmptparm[j].h = (OPJ_UINT32)h;
+ }
+
+ image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
+ if (!image) {
+ TIFFClose(tif);
+ return NULL;
+ }
+ /* set image offset and reference grid */
+ image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
+ image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
+ image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 :
+ image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
+ if (image->x1 <= image->x0) {
+ fprintf(stderr, "tiftoimage: Bad value for image->x1(%d) vs. "
+ "image->x0(%d)\n\tAborting.\n", image->x1, image->x0);
+ TIFFClose(tif);
+ opj_image_destroy(image);
+ return NULL;
+ }
+ image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 :
+ image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1;
+ if (image->y1 <= image->y0) {
+ fprintf(stderr, "tiftoimage: Bad value for image->y1(%d) vs. "
+ "image->y0(%d)\n\tAborting.\n", image->y1, image->y0);
+ TIFFClose(tif);
+ opj_image_destroy(image);
+ return NULL;
+ }
+
+ for (j = 0; j < numcomps; j++) {
+ planes[j] = image->comps[j].data;
+ }
+ image->comps[numcomps - 1].alpha = (OPJ_UINT16)(1 - (numcomps & 1));
+
+ strip_size = (int64_t)TIFFStripSize(tif);
+
+ buf = malloc((OPJ_SIZE_T)strip_size);
+ if (buf == NULL) {
+ TIFFClose(tif);
+ opj_image_destroy(image);
+ return NULL;
+ }
+ if (sizeof(tsize_t) == 4) {
+ TIFF_MAX = INT_MAX;
+ } else {
+ TIFF_MAX = UINT_MAX;
+ }
+ if ((int64_t)tiWidth > (int64_t)(TIFF_MAX / tiSpp) ||
+ (int64_t)(tiWidth * tiSpp) > (int64_t)(TIFF_MAX / tiBps) ||
+ (int64_t)(tiWidth * tiSpp) > (int64_t)(TIFF_MAX / (int64_t)sizeof(OPJ_INT32))) {
+ fprintf(stderr, "Buffer overflow\n");
+ _TIFFfree(buf);
+ TIFFClose(tif);
+ opj_image_destroy(image);
+ return NULL;
+ }
+
+ rowStride = (int64_t)((tiWidth * tiSpp * tiBps + 7U) / 8U);
+ buffer32s = (OPJ_INT32 *)malloc((OPJ_SIZE_T)(tiWidth * tiSpp * sizeof(
+ OPJ_INT32)));
+ if (buffer32s == NULL) {
+ _TIFFfree(buf);
+ TIFFClose(tif);
+ opj_image_destroy(image);
+ return NULL;
+ }
+
+ strip = 0;
+ currentPlane = 0;
+ do {
+ planes[0] = image->comps[currentPlane].data; /* to manage planar data */
+ h = (int)tiHeight;
+ /* Read the Image components */
+ for (; (h > 0) && (strip < TIFFNumberOfStrips(tif)); strip++) {
+ const OPJ_UINT8 *dat8;
+ int64_t ssize;
+
+ ssize = (int64_t)TIFFReadEncodedStrip(tif, strip, buf, (tsize_t)strip_size);
+
+ if (ssize < 1 || ssize > strip_size) {
+ fprintf(stderr, "tiftoimage: Bad value for ssize(%" PRId64 ") "
+ "vs. strip_size(%" PRId64 ").\n\tAborting.\n", ssize, strip_size);
+ _TIFFfree(buf);
+ _TIFFfree(buffer32s);
+ TIFFClose(tif);
+ opj_image_destroy(image);
+ return NULL;
+ }
+ dat8 = (const OPJ_UINT8*)buf;
+
+ while (ssize >= rowStride) {
+ cvtTifTo32s(dat8, buffer32s, (OPJ_SIZE_T)w * tiSpp);
+ cvtCxToPx(buffer32s, planes, (OPJ_SIZE_T)w);
+ planes[0] += w;
+ planes[1] += w;
+ planes[2] += w;
+ planes[3] += w;
+ dat8 += rowStride;
+ ssize -= rowStride;
+ h--;
+ }
+ }
+ currentPlane++;
+ } while ((tiPC == PLANARCONFIG_SEPARATE) && (currentPlane < numcomps));
+
+ free(buffer32s);
+ _TIFFfree(buf);
+ TIFFClose(tif);
+
+ if (is_cinema) {
+ for (j = 0; j < numcomps; ++j) {
+ scale_component(&(image->comps[j]), 12);
+ }
+
+ }
+ return image;