}
}
-opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
+static opj_image_t * pngtoimage_internal(opj_cparameters_t * params,
+ FILE *reader,
+ png_structp png,
+ png_infop info,
+ png_uint_32* pheight,
+ OPJ_BYTE*** prows,
+ OPJ_INT32** prow32s)
{
- png_structp png = NULL;
- png_infop info = NULL;
- double gamma;
- int bit_depth, interlace_type, compression_type, filter_type;
- OPJ_UINT32 i;
- png_uint_32 width, height = 0U;
- int color_type;
- FILE *reader = NULL;
- OPJ_BYTE** rows = NULL;
- OPJ_INT32* row32s = NULL;
- /* j2k: */
- opj_image_t *image = NULL;
- opj_image_cmptparm_t cmptparm[4];
- OPJ_UINT32 nr_comp;
- OPJ_BYTE sigbuf[8];
- convert_XXx32s_C1R cvtXXTo32s = NULL;
- convert_32s_CXPX cvtCxToPx = NULL;
- OPJ_INT32* planes[4];
+ *pheight = 0;
+ *prows = NULL;
+ *prow32s = NULL;
- if ((reader = fopen(read_idf, "rb")) == NULL) {
- fprintf(stderr, "pngtoimage: can not open %s\n", read_idf);
+ if (setjmp(png_jmpbuf(png))) {
return NULL;
}
- if (fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE
- || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0) {
- fprintf(stderr, "pngtoimage: %s is no valid PNG file\n", read_idf);
- goto fin;
- }
-
- if ((png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL)) == NULL) {
- goto fin;
- }
- if ((info = png_create_info_struct(png)) == NULL) {
- goto fin;
- }
+ {
+ opj_image_t *image = NULL;
+ opj_image_cmptparm_t cmptparm[4];
+ OPJ_UINT32 nr_comp;
+ convert_XXx32s_C1R cvtXXTo32s = NULL;
+ convert_32s_CXPX cvtCxToPx = NULL;
+ OPJ_INT32* planes[4];
+ double gamma;
+ int bit_depth, interlace_type, compression_type, filter_type;
+ OPJ_UINT32 i;
+ png_uint_32 width, height = 0U;
+ int color_type;
+ OPJ_BYTE** rows = NULL;
+ OPJ_INT32* row32s = NULL;
+
+ png_init_io(png, reader);
+ png_set_sig_bytes(png, MAGIC_SIZE);
+
+ png_read_info(png, info);
+
+ if (png_get_IHDR(png, info, &width, &height,
+ &bit_depth, &color_type, &interlace_type,
+ &compression_type, &filter_type) == 0) {
+ return image;
+ }
+ *pheight = height;
+
+ /* png_set_expand():
+ * expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+ if (color_type == PNG_COLOR_TYPE_PALETTE) {
+ png_set_expand(png);
+ }
- if (setjmp(png_jmpbuf(png))) {
- goto fin;
- }
+ if (png_get_valid(png, info, PNG_INFO_tRNS)) {
+ png_set_expand(png);
+ }
+ /* We might wan't to expand background */
+ /*
+ if(png_get_valid(png, info, PNG_INFO_bKGD)) {
+ png_color_16p bgnd;
+ png_get_bKGD(png, info, &bgnd);
+ png_set_background(png, bgnd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ }
+ */
- png_init_io(png, reader);
- png_set_sig_bytes(png, MAGIC_SIZE);
+ if (!png_get_gAMA(png, info, &gamma)) {
+ gamma = 1.0;
+ }
- png_read_info(png, info);
+ /* we're not displaying but converting, screen gamma == 1.0 */
+ png_set_gamma(png, 1.0, gamma);
- if (png_get_IHDR(png, info, &width, &height,
- &bit_depth, &color_type, &interlace_type,
- &compression_type, &filter_type) == 0) {
- goto fin;
- }
+ png_read_update_info(png, info);
- /* png_set_expand():
- * expand paletted images to RGB, expand grayscale images of
- * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
- * to alpha channels.
- */
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- png_set_expand(png);
- }
+ color_type = png_get_color_type(png, info);
- if (png_get_valid(png, info, PNG_INFO_tRNS)) {
- png_set_expand(png);
- }
- /* We might wan't to expand background */
- /*
- if(png_get_valid(png, info, PNG_INFO_bKGD)) {
- png_color_16p bgnd;
- png_get_bKGD(png, info, &bgnd);
- png_set_background(png, bgnd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
- }
- */
+ switch (color_type) {
+ case PNG_COLOR_TYPE_GRAY:
+ nr_comp = 1;
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ nr_comp = 2;
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ nr_comp = 3;
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ nr_comp = 4;
+ break;
+ default:
+ fprintf(stderr, "pngtoimage: colortype %d is not supported\n", color_type);
+ return image;
+ }
+ cvtCxToPx = convert_32s_CXPX_LUT[nr_comp];
+ bit_depth = png_get_bit_depth(png, info);
- if (!png_get_gAMA(png, info, &gamma)) {
- gamma = 1.0;
- }
+ switch (bit_depth) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ cvtXXTo32s = convert_XXu32s_C1R_LUT[bit_depth];
+ break;
+ case 16: /* 16 bpp is specific to PNG */
+ cvtXXTo32s = convert_16u32s_C1R;
+ break;
+ default:
+ fprintf(stderr, "pngtoimage: bit depth %d is not supported\n", bit_depth);
+ return image;
+ }
- /* we're not displaying but converting, screen gamma == 1.0 */
- png_set_gamma(png, 1.0, gamma);
+ rows = (OPJ_BYTE**)calloc(height + 1, sizeof(OPJ_BYTE*));
+ if (rows == NULL) {
+ fprintf(stderr, "pngtoimage: memory out\n");
+ return image;
+ }
+ *prows = rows;
+ for (i = 0; i < height; ++i) {
+ rows[i] = (OPJ_BYTE*)malloc(png_get_rowbytes(png, info));
+ if (rows[i] == NULL) {
+ fprintf(stderr, "pngtoimage: memory out\n");
+ return image;
+ }
+ }
+ png_read_image(png, rows);
- png_read_update_info(png, info);
+ /* Create image */
+ memset(cmptparm, 0, sizeof(cmptparm));
+ for (i = 0; i < nr_comp; ++i) {
+ cmptparm[i].prec = (OPJ_UINT32)bit_depth;
+ /* bits_per_pixel: 8 or 16 */
+ cmptparm[i].bpp = (OPJ_UINT32)bit_depth;
+ cmptparm[i].sgnd = 0;
+ cmptparm[i].dx = (OPJ_UINT32)params->subsampling_dx;
+ cmptparm[i].dy = (OPJ_UINT32)params->subsampling_dy;
+ cmptparm[i].w = (OPJ_UINT32)width;
+ cmptparm[i].h = (OPJ_UINT32)height;
+ }
- color_type = png_get_color_type(png, info);
+ image = opj_image_create(nr_comp, &cmptparm[0],
+ (nr_comp > 2U) ? OPJ_CLRSPC_SRGB : OPJ_CLRSPC_GRAY);
+ if (image == NULL) {
+ return image;
+ }
+ image->x0 = (OPJ_UINT32)params->image_offset_x0;
+ image->y0 = (OPJ_UINT32)params->image_offset_y0;
+ image->x1 = (OPJ_UINT32)(image->x0 + (width - 1) * (OPJ_UINT32)
+ params->subsampling_dx + 1);
+ image->y1 = (OPJ_UINT32)(image->y0 + (height - 1) * (OPJ_UINT32)
+ params->subsampling_dy + 1);
+
+ row32s = (OPJ_INT32 *)malloc((size_t)width * nr_comp * sizeof(OPJ_INT32));
+ if (row32s == NULL) {
+ return image;
+ }
+ *prow32s = row32s;
- switch (color_type) {
- case PNG_COLOR_TYPE_GRAY:
- nr_comp = 1;
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- nr_comp = 2;
- break;
- case PNG_COLOR_TYPE_RGB:
- nr_comp = 3;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- nr_comp = 4;
- break;
- default:
- fprintf(stderr, "pngtoimage: colortype %d is not supported\n", color_type);
- goto fin;
- }
- cvtCxToPx = convert_32s_CXPX_LUT[nr_comp];
- bit_depth = png_get_bit_depth(png, info);
-
- switch (bit_depth) {
- case 1:
- case 2:
- case 4:
- case 8:
- cvtXXTo32s = convert_XXu32s_C1R_LUT[bit_depth];
- break;
- case 16: /* 16 bpp is specific to PNG */
- cvtXXTo32s = convert_16u32s_C1R;
- break;
- default:
- fprintf(stderr, "pngtoimage: bit depth %d is not supported\n", bit_depth);
- goto fin;
- }
+ /* Set alpha channel */
+ image->comps[nr_comp - 1U].alpha = 1U - (nr_comp & 1U);
+ for (i = 0; i < nr_comp; i++) {
+ planes[i] = image->comps[i].data;
+ }
- rows = (OPJ_BYTE**)calloc(height + 1, sizeof(OPJ_BYTE*));
- if (rows == NULL) {
- fprintf(stderr, "pngtoimage: memory out\n");
- goto fin;
- }
- for (i = 0; i < height; ++i) {
- rows[i] = (OPJ_BYTE*)malloc(png_get_rowbytes(png, info));
- if (rows[i] == NULL) {
- fprintf(stderr, "pngtoimage: memory out\n");
- goto fin;
+ for (i = 0; i < height; ++i) {
+ cvtXXTo32s(rows[i], row32s, (OPJ_SIZE_T)width * nr_comp);
+ cvtCxToPx(row32s, planes, width);
+ planes[0] += width;
+ planes[1] += width;
+ planes[2] += width;
+ planes[3] += width;
}
+
+ return image;
}
- png_read_image(png, rows);
+}
- /* Create image */
- memset(cmptparm, 0, sizeof(cmptparm));
- for (i = 0; i < nr_comp; ++i) {
- cmptparm[i].prec = (OPJ_UINT32)bit_depth;
- /* bits_per_pixel: 8 or 16 */
- cmptparm[i].bpp = (OPJ_UINT32)bit_depth;
- cmptparm[i].sgnd = 0;
- cmptparm[i].dx = (OPJ_UINT32)params->subsampling_dx;
- cmptparm[i].dy = (OPJ_UINT32)params->subsampling_dy;
- cmptparm[i].w = (OPJ_UINT32)width;
- cmptparm[i].h = (OPJ_UINT32)height;
+opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
+{
+ png_structp png = NULL;
+ png_infop info = NULL;
+ OPJ_UINT32 i;
+ png_uint_32 height = 0U;
+ FILE *reader = NULL;
+ OPJ_BYTE** rows = NULL;
+ OPJ_INT32* row32s = NULL;
+ OPJ_BYTE sigbuf[8];
+ opj_image_t *image = NULL;
+
+ if ((reader = fopen(read_idf, "rb")) == NULL) {
+ fprintf(stderr, "pngtoimage: can not open %s\n", read_idf);
+ return NULL;
}
- image = opj_image_create(nr_comp, &cmptparm[0],
- (nr_comp > 2U) ? OPJ_CLRSPC_SRGB : OPJ_CLRSPC_GRAY);
- if (image == NULL) {
+ if (fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE
+ || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0) {
+ fprintf(stderr, "pngtoimage: %s is no valid PNG file\n", read_idf);
goto fin;
}
- image->x0 = (OPJ_UINT32)params->image_offset_x0;
- image->y0 = (OPJ_UINT32)params->image_offset_y0;
- image->x1 = (OPJ_UINT32)(image->x0 + (width - 1) * (OPJ_UINT32)
- params->subsampling_dx + 1);
- image->y1 = (OPJ_UINT32)(image->y0 + (height - 1) * (OPJ_UINT32)
- params->subsampling_dy + 1);
-
- row32s = (OPJ_INT32 *)malloc((size_t)width * nr_comp * sizeof(OPJ_INT32));
- if (row32s == NULL) {
+
+ if ((png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+ NULL, NULL, NULL)) == NULL) {
goto fin;
}
-
- /* Set alpha channel */
- image->comps[nr_comp - 1U].alpha = 1U - (nr_comp & 1U);
-
- for (i = 0; i < nr_comp; i++) {
- planes[i] = image->comps[i].data;
+ if ((info = png_create_info_struct(png)) == NULL) {
+ goto fin;
}
- for (i = 0; i < height; ++i) {
- cvtXXTo32s(rows[i], row32s, (OPJ_SIZE_T)width * nr_comp);
- cvtCxToPx(row32s, planes, width);
- planes[0] += width;
- planes[1] += width;
- planes[2] += width;
- planes[3] += width;
- }
+ image = pngtoimage_internal(params, reader, png, info, &height, &rows, &row32s);
fin:
if (rows) {
for (i = 0; i < height; ++i)