Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/imbuf/intern/png.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/imbuf/intern/png.c')
-rw-r--r--source/blender/imbuf/intern/png.c1357
1 files changed, 694 insertions, 663 deletions
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index e51f24f67d8..27cf30c71ba 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -45,9 +45,9 @@
#include "IMB_colormanagement_intern.h"
typedef struct PNGReadStruct {
- const unsigned char *data;
- unsigned int size;
- unsigned int seek;
+ const unsigned char *data;
+ unsigned int size;
+ unsigned int seek;
} PNGReadStruct;
static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length);
@@ -56,719 +56,750 @@ static void Flush(png_structp png_ptr);
BLI_INLINE unsigned short UPSAMPLE_8_TO_16(const unsigned char _val)
{
- return (_val << 8) + _val;
+ return (_val << 8) + _val;
}
int imb_is_a_png(const unsigned char *mem)
{
- int ret_val = 0;
+ int ret_val = 0;
- if (mem) {
+ if (mem) {
#if (PNG_LIBPNG_VER_MAJOR == 1) && (PNG_LIBPNG_VER_MINOR == 2)
- /* Older version of libpng doesn't use const pointer to memory. */
- ret_val = !png_sig_cmp((png_bytep)mem, 0, 8);
+ /* Older version of libpng doesn't use const pointer to memory. */
+ ret_val = !png_sig_cmp((png_bytep)mem, 0, 8);
#else
- ret_val = !png_sig_cmp(mem, 0, 8);
+ ret_val = !png_sig_cmp(mem, 0, 8);
#endif
- }
- return(ret_val);
+ }
+ return (ret_val);
}
static void Flush(png_structp png_ptr)
{
- (void)png_ptr;
+ (void)png_ptr;
}
static void WriteData(png_structp png_ptr, png_bytep data, png_size_t length)
{
- ImBuf *ibuf = (ImBuf *) png_get_io_ptr(png_ptr);
+ ImBuf *ibuf = (ImBuf *)png_get_io_ptr(png_ptr);
- /* if buffer is to small increase it. */
- while (ibuf->encodedsize + length > ibuf->encodedbuffersize) {
- imb_enlargeencodedbufferImBuf(ibuf);
- }
+ /* if buffer is to small increase it. */
+ while (ibuf->encodedsize + length > ibuf->encodedbuffersize) {
+ imb_enlargeencodedbufferImBuf(ibuf);
+ }
- memcpy(ibuf->encodedbuffer + ibuf->encodedsize, data, length);
- ibuf->encodedsize += length;
+ memcpy(ibuf->encodedbuffer + ibuf->encodedsize, data, length);
+ ibuf->encodedsize += length;
}
static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length)
{
- PNGReadStruct *rs = (PNGReadStruct *) png_get_io_ptr(png_ptr);
-
- if (rs) {
- if (length <= rs->size - rs->seek) {
- memcpy(data, rs->data + rs->seek, length);
- rs->seek += length;
- return;
- }
- }
-
- printf("Reached EOF while decoding PNG\n");
- longjmp(png_jmpbuf(png_ptr), 1);
+ PNGReadStruct *rs = (PNGReadStruct *)png_get_io_ptr(png_ptr);
+
+ if (rs) {
+ if (length <= rs->size - rs->seek) {
+ memcpy(data, rs->data + rs->seek, length);
+ rs->seek += length;
+ return;
+ }
+ }
+
+ printf("Reached EOF while decoding PNG\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
}
static float channel_colormanage_noop(float value)
{
- return value;
+ return value;
}
/* wrap to avoid macro calling functions multiple times */
BLI_INLINE unsigned short ftoshort(float val)
{
- return unit_float_to_ushort_clamp(val);
+ return unit_float_to_ushort_clamp(val);
}
int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
{
- png_structp png_ptr;
- png_infop info_ptr;
-
- unsigned char *pixels = NULL;
- unsigned char *from, *to;
- unsigned short *pixels16 = NULL, *to16;
- float *from_float, from_straight[4];
- png_bytepp row_pointers = NULL;
- int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
- FILE *fp = NULL;
-
- bool is_16bit = (ibuf->foptions.flag & PNG_16BIT) != 0;
- bool has_float = (ibuf->rect_float != NULL);
- int channels_in_float = ibuf->channels ? ibuf->channels : 4;
-
- float (*chanel_colormanage_cb)(float);
- size_t num_bytes;
-
- /* use the jpeg quality setting for compression */
- int compression;
- compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f));
- compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);
-
- if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
- /* float buffer was managed already, no need in color space conversion */
- chanel_colormanage_cb = channel_colormanage_noop;
- }
- else {
- /* standard linear-to-srgb conversion if float buffer wasn't managed */
- chanel_colormanage_cb = linearrgb_to_srgb;
- }
-
- /* for prints */
- if (flags & IB_mem)
- name = "<memory>";
-
- bytesperpixel = (ibuf->planes + 7) >> 3;
- if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
- printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
- return (0);
- }
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- if (png_ptr == NULL) {
- printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", name);
- return 0;
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", name);
- return 0;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- printf("imb_savepng: Cannot setjmp for file: '%s'\n", name);
- return 0;
- }
-
- /* copy image data */
- num_bytes = ((size_t)ibuf->x) * ibuf->y * bytesperpixel;
- if (is_16bit)
- pixels16 = MEM_mallocN(num_bytes * sizeof(unsigned short), "png 16bit pixels");
- else
- pixels = MEM_mallocN(num_bytes * sizeof(unsigned char), "png 8bit pixels");
-
- if (pixels == NULL && pixels16 == NULL) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- printf("imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n", ibuf->x, ibuf->y, bytesperpixel, name);
- return 0;
- }
-
- from = (unsigned char *) ibuf->rect;
- to = pixels;
- from_float = ibuf->rect_float;
- to16 = pixels16;
-
- switch (bytesperpixel) {
- case 4:
- color_type = PNG_COLOR_TYPE_RGBA;
- if (is_16bit) {
- if (has_float) {
- if (channels_in_float == 4) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
- to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
- to16 += 4; from_float += 4;
- }
- }
- else if (channels_in_float == 3) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
- to16[3] = 65535;
- to16 += 4; from_float += 3;
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[2] = to16[1] = to16[0];
- to16[3] = 65535;
- to16 += 4; from_float++;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = UPSAMPLE_8_TO_16(from[0]);
- to16[1] = UPSAMPLE_8_TO_16(from[1]);
- to16[2] = UPSAMPLE_8_TO_16(from[2]);
- to16[3] = UPSAMPLE_8_TO_16(from[3]);
- to16 += 4; from += 4;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = from[3];
- to += 4; from += 4;
- }
- }
- break;
- case 3:
- color_type = PNG_COLOR_TYPE_RGB;
- if (is_16bit) {
- if (has_float) {
- if (channels_in_float == 4) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
- to16 += 3; from_float += 4;
- }
- }
- else if (channels_in_float == 3) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
- to16 += 3; from_float += 3;
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[2] = to16[1] = to16[0];
- to16 += 3; from_float++;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = UPSAMPLE_8_TO_16(from[0]);
- to16[1] = UPSAMPLE_8_TO_16(from[1]);
- to16[2] = UPSAMPLE_8_TO_16(from[2]);
- to16 += 3; from += 4;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to += 3; from += 4;
- }
- }
- break;
- case 1:
- color_type = PNG_COLOR_TYPE_GRAY;
- if (is_16bit) {
- if (has_float) {
- float rgb[3];
- if (channels_in_float == 4) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- rgb[0] = chanel_colormanage_cb(from_straight[0]);
- rgb[1] = chanel_colormanage_cb(from_straight[1]);
- rgb[2] = chanel_colormanage_cb(from_straight[2]);
- to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
- to16++; from_float += 4;
- }
- }
- else if (channels_in_float == 3) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- rgb[0] = chanel_colormanage_cb(from_float[0]);
- rgb[1] = chanel_colormanage_cb(from_float[1]);
- rgb[2] = chanel_colormanage_cb(from_float[2]);
- to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
- to16++; from_float += 3;
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16++; from_float++;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = UPSAMPLE_8_TO_16(from[0]);
- to16++; from += 4;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to++; from += 4;
- }
- }
- break;
- }
-
- if (flags & IB_mem) {
- /* create image in memory */
- imb_addencodedbufferImBuf(ibuf);
- ibuf->encodedsize = 0;
-
- png_set_write_fn(png_ptr,
- (png_voidp) ibuf,
- WriteData,
- Flush);
- }
- else {
- fp = BLI_fopen(name, "wb");
- if (!fp) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- printf("imb_savepng: Cannot open file for writing: '%s'\n", name);
- return 0;
- }
- png_init_io(png_ptr, fp);
- }
+ png_structp png_ptr;
+ png_infop info_ptr;
+
+ unsigned char *pixels = NULL;
+ unsigned char *from, *to;
+ unsigned short *pixels16 = NULL, *to16;
+ float *from_float, from_straight[4];
+ png_bytepp row_pointers = NULL;
+ int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
+ FILE *fp = NULL;
+
+ bool is_16bit = (ibuf->foptions.flag & PNG_16BIT) != 0;
+ bool has_float = (ibuf->rect_float != NULL);
+ int channels_in_float = ibuf->channels ? ibuf->channels : 4;
+
+ float (*chanel_colormanage_cb)(float);
+ size_t num_bytes;
+
+ /* use the jpeg quality setting for compression */
+ int compression;
+ compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f));
+ compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);
+
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
+ /* float buffer was managed already, no need in color space conversion */
+ chanel_colormanage_cb = channel_colormanage_noop;
+ }
+ else {
+ /* standard linear-to-srgb conversion if float buffer wasn't managed */
+ chanel_colormanage_cb = linearrgb_to_srgb;
+ }
+
+ /* for prints */
+ if (flags & IB_mem)
+ name = "<memory>";
+
+ bytesperpixel = (ibuf->planes + 7) >> 3;
+ if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
+ printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
+ return (0);
+ }
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (png_ptr == NULL) {
+ printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", name);
+ return 0;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", name);
+ return 0;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ printf("imb_savepng: Cannot setjmp for file: '%s'\n", name);
+ return 0;
+ }
+
+ /* copy image data */
+ num_bytes = ((size_t)ibuf->x) * ibuf->y * bytesperpixel;
+ if (is_16bit)
+ pixels16 = MEM_mallocN(num_bytes * sizeof(unsigned short), "png 16bit pixels");
+ else
+ pixels = MEM_mallocN(num_bytes * sizeof(unsigned char), "png 8bit pixels");
+
+ if (pixels == NULL && pixels16 == NULL) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ printf(
+ "imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n",
+ ibuf->x,
+ ibuf->y,
+ bytesperpixel,
+ name);
+ return 0;
+ }
+
+ from = (unsigned char *)ibuf->rect;
+ to = pixels;
+ from_float = ibuf->rect_float;
+ to16 = pixels16;
+
+ switch (bytesperpixel) {
+ case 4:
+ color_type = PNG_COLOR_TYPE_RGBA;
+ if (is_16bit) {
+ if (has_float) {
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
+ to16 += 4;
+ from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16[3] = 65535;
+ to16 += 4;
+ from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16[3] = 65535;
+ to16 += 4;
+ from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16[1] = UPSAMPLE_8_TO_16(from[1]);
+ to16[2] = UPSAMPLE_8_TO_16(from[2]);
+ to16[3] = UPSAMPLE_8_TO_16(from[3]);
+ to16 += 4;
+ from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+ to += 4;
+ from += 4;
+ }
+ }
+ break;
+ case 3:
+ color_type = PNG_COLOR_TYPE_RGB;
+ if (is_16bit) {
+ if (has_float) {
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16 += 3;
+ from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16 += 3;
+ from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16 += 3;
+ from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16[1] = UPSAMPLE_8_TO_16(from[1]);
+ to16[2] = UPSAMPLE_8_TO_16(from[2]);
+ to16 += 3;
+ from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to += 3;
+ from += 4;
+ }
+ }
+ break;
+ case 1:
+ color_type = PNG_COLOR_TYPE_GRAY;
+ if (is_16bit) {
+ if (has_float) {
+ float rgb[3];
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ rgb[0] = chanel_colormanage_cb(from_straight[0]);
+ rgb[1] = chanel_colormanage_cb(from_straight[1]);
+ rgb[2] = chanel_colormanage_cb(from_straight[2]);
+ to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
+ to16++;
+ from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ rgb[0] = chanel_colormanage_cb(from_float[0]);
+ rgb[1] = chanel_colormanage_cb(from_float[1]);
+ rgb[2] = chanel_colormanage_cb(from_float[2]);
+ to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
+ to16++;
+ from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16++;
+ from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16++;
+ from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to++;
+ from += 4;
+ }
+ }
+ break;
+ }
+
+ if (flags & IB_mem) {
+ /* create image in memory */
+ imb_addencodedbufferImBuf(ibuf);
+ ibuf->encodedsize = 0;
+
+ png_set_write_fn(png_ptr, (png_voidp)ibuf, WriteData, Flush);
+ }
+ else {
+ fp = BLI_fopen(name, "wb");
+ if (!fp) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ printf("imb_savepng: Cannot open file for writing: '%s'\n", name);
+ return 0;
+ }
+ png_init_io(png_ptr, fp);
+ }
#if 0
- png_set_filter(png_ptr, 0,
- PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE |
- PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB |
- PNG_FILTER_UP | PNG_FILTER_VALUE_UP |
- PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG |
- PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH |
- PNG_ALL_FILTERS);
+ png_set_filter(png_ptr, 0,
+ PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE |
+ PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB |
+ PNG_FILTER_UP | PNG_FILTER_VALUE_UP |
+ PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG |
+ PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH |
+ PNG_ALL_FILTERS);
#endif
- png_set_compression_level(png_ptr, compression);
-
- /* png image settings */
- png_set_IHDR(png_ptr,
- info_ptr,
- ibuf->x,
- ibuf->y,
- is_16bit ? 16 : 8,
- color_type,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT);
-
- /* image text info */
- if (ibuf->metadata) {
- png_text *metadata;
- IDProperty *prop;
-
- int num_text = 0;
-
- for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
- if (prop->type == IDP_STRING) {
- num_text++;
- }
- }
-
- metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata");
- num_text = 0;
- for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
- if (prop->type == IDP_STRING) {
- metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- metadata[num_text].key = prop->name;
- metadata[num_text].text = IDP_String(prop);
- num_text++;
- }
- }
-
- png_set_text(png_ptr, info_ptr, metadata, num_text);
- MEM_freeN(metadata);
-
- }
-
- if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
- png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER);
- }
-
- /* write the file header information */
- png_write_info(png_ptr, info_ptr);
+ png_set_compression_level(png_ptr, compression);
+
+ /* png image settings */
+ png_set_IHDR(png_ptr,
+ info_ptr,
+ ibuf->x,
+ ibuf->y,
+ is_16bit ? 16 : 8,
+ color_type,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ /* image text info */
+ if (ibuf->metadata) {
+ png_text *metadata;
+ IDProperty *prop;
+
+ int num_text = 0;
+
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ num_text++;
+ }
+ }
+
+ metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata");
+ num_text = 0;
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
+ metadata[num_text].key = prop->name;
+ metadata[num_text].text = IDP_String(prop);
+ num_text++;
+ }
+ }
+
+ png_set_text(png_ptr, info_ptr, metadata, num_text);
+ MEM_freeN(metadata);
+ }
+
+ if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+ png_set_pHYs(png_ptr,
+ info_ptr,
+ (unsigned int)(ibuf->ppm[0] + 0.5),
+ (unsigned int)(ibuf->ppm[1] + 0.5),
+ PNG_RESOLUTION_METER);
+ }
+
+ /* write the file header information */
+ png_write_info(png_ptr, info_ptr);
#ifdef __LITTLE_ENDIAN__
- png_set_swap(png_ptr);
+ png_set_swap(png_ptr);
#endif
- /* allocate memory for an array of row-pointers */
- row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
- if (row_pointers == NULL) {
- printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name);
- png_destroy_write_struct(&png_ptr, &info_ptr);
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- if (fp) {
- fclose(fp);
- }
- return 0;
- }
-
- /* set the individual row-pointers to point at the correct offsets */
- if (is_16bit) {
- for (i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned short *)pixels16 + (((size_t)i) * ibuf->x) * bytesperpixel);
- }
- }
- else {
- for (i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned char *)pixels + (((size_t)i) * ibuf->x) * bytesperpixel * sizeof(unsigned char));
- }
- }
-
- /* write out the entire image data in one call */
- png_write_image(png_ptr, row_pointers);
-
- /* write the additional chunks to the PNG file (not really needed) */
- png_write_end(png_ptr, info_ptr);
-
- /* clean up */
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- MEM_freeN(row_pointers);
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- if (fp) {
- fflush(fp);
- fclose(fp);
- }
-
- return(1);
+ /* allocate memory for an array of row-pointers */
+ row_pointers = (png_bytepp)MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
+ if (row_pointers == NULL) {
+ printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ if (fp) {
+ fclose(fp);
+ }
+ return 0;
+ }
+
+ /* set the individual row-pointers to point at the correct offsets */
+ if (is_16bit) {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)((unsigned short *)pixels16 +
+ (((size_t)i) * ibuf->x) * bytesperpixel);
+ }
+ }
+ else {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)((unsigned char *)pixels +
+ (((size_t)i) * ibuf->x) * bytesperpixel *
+ sizeof(unsigned char));
+ }
+ }
+
+ /* write out the entire image data in one call */
+ png_write_image(png_ptr, row_pointers);
+
+ /* write the additional chunks to the PNG file (not really needed) */
+ png_write_end(png_ptr, info_ptr);
+
+ /* clean up */
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ MEM_freeN(row_pointers);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ if (fp) {
+ fflush(fp);
+ fclose(fp);
+ }
+
+ return (1);
}
static void imb_png_warning(png_structp UNUSED(png_ptr), png_const_charp message)
{
- /* We suppress iCCP warnings. That's how Blender always used to behave,
- * and with new libpng it became too much picky, giving a warning on
- * the splash screen even.
- */
- if ((G.debug & G_DEBUG) == 0 && STREQLEN(message, "iCCP", 4)) {
- return;
- }
- fprintf(stderr, "libpng warning: %s\n", message);
+ /* We suppress iCCP warnings. That's how Blender always used to behave,
+ * and with new libpng it became too much picky, giving a warning on
+ * the splash screen even.
+ */
+ if ((G.debug & G_DEBUG) == 0 && STREQLEN(message, "iCCP", 4)) {
+ return;
+ }
+ fprintf(stderr, "libpng warning: %s\n", message);
}
static void imb_png_error(png_structp UNUSED(png_ptr), png_const_charp message)
{
- fprintf(stderr, "libpng error: %s\n", message);
+ fprintf(stderr, "libpng error: %s\n", message);
}
ImBuf *imb_loadpng(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
{
- struct ImBuf *ibuf = NULL;
- png_structp png_ptr;
- png_infop info_ptr;
- unsigned char *pixels = NULL;
- unsigned short *pixels16 = NULL;
- png_bytepp row_pointers = NULL;
- png_uint_32 width, height;
- int bit_depth, color_type;
- PNGReadStruct ps;
-
- unsigned char *from, *to;
- unsigned short *from16;
- float *to_float;
- unsigned int channels;
-
- if (imb_is_a_png(mem) == 0) return(NULL);
-
- /* both 8 and 16 bit PNGs are default to standard byte colorspace */
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- if (png_ptr == NULL) {
- printf("Cannot png_create_read_struct\n");
- return NULL;
- }
-
- png_set_error_fn(png_ptr, NULL, imb_png_error, imb_png_warning);
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
- (png_infopp)NULL);
- printf("Cannot png_create_info_struct\n");
- return NULL;
- }
-
- ps.size = size; /* XXX, 4gig limit! */
- ps.data = mem;
- ps.seek = 0;
-
- png_set_read_fn(png_ptr, (void *) &ps, ReadData);
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- if (pixels) MEM_freeN(pixels);
- if (pixels16) MEM_freeN(pixels16);
- if (row_pointers) MEM_freeN(row_pointers);
- if (ibuf) IMB_freeImBuf(ibuf);
- return NULL;
- }
-
- // png_set_sig_bytes(png_ptr, 8);
-
- png_read_info(png_ptr, info_ptr);
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
- &color_type, NULL, NULL, NULL);
-
- channels = png_get_channels(png_ptr, info_ptr);
-
- switch (color_type) {
- case PNG_COLOR_TYPE_RGB:
- case PNG_COLOR_TYPE_RGB_ALPHA:
- break;
- case PNG_COLOR_TYPE_PALETTE:
- png_set_palette_to_rgb(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- channels = 4;
- }
- else {
- channels = 3;
- }
- break;
- case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- if (bit_depth < 8) {
- png_set_expand(png_ptr);
- bit_depth = 8;
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- /* PNG_COLOR_TYPE_GRAY may also have alpha 'values', like with palette. */
- channels = 2;
- }
- }
- break;
- default:
- printf("PNG format not supported\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- ibuf = IMB_allocImBuf(width, height, 8 * channels, 0);
-
- if (ibuf) {
- ibuf->ftype = IMB_FTYPE_PNG;
- if (bit_depth == 16)
- ibuf->foptions.flag |= PNG_16BIT;
-
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
- int unit_type;
- png_uint_32 xres, yres;
-
- if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) {
- if (unit_type == PNG_RESOLUTION_METER) {
- ibuf->ppm[0] = xres;
- ibuf->ppm[1] = yres;
- }
- }
- }
- }
- else {
- printf("Couldn't allocate memory for PNG image\n");
- }
-
- if (ibuf && ((flags & IB_test) == 0)) {
- if (bit_depth == 16) {
- imb_addrectfloatImBuf(ibuf);
- png_set_swap(png_ptr);
-
- pixels16 = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(png_uint_16), "pixels");
- if (pixels16 == NULL || ibuf->rect_float == NULL) {
- printf("Cannot allocate pixels array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* allocate memory for an array of row-pointers */
- row_pointers = (png_bytepp) MEM_mallocN((size_t)ibuf->y * sizeof(png_uint_16p), "row_pointers");
- if (row_pointers == NULL) {
- printf("Cannot allocate row-pointers array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* set the individual row-pointers to point at the correct offsets */
- for (size_t i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((png_uint_16 *)pixels16 + (i * ibuf->x) * channels);
- }
-
- png_read_image(png_ptr, row_pointers);
-
- /* copy image data */
-
- to_float = ibuf->rect_float;
- from16 = pixels16;
-
- switch (channels) {
- case 4:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = from16[0] / 65535.0;
- to_float[1] = from16[1] / 65535.0;
- to_float[2] = from16[2] / 65535.0;
- to_float[3] = from16[3] / 65535.0;
- to_float += 4; from16 += 4;
- }
- break;
- case 3:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = from16[0] / 65535.0;
- to_float[1] = from16[1] / 65535.0;
- to_float[2] = from16[2] / 65535.0;
- to_float[3] = 1.0;
- to_float += 4; from16 += 3;
- }
- break;
- case 2:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
- to_float[3] = from16[1] / 65535.0;
- to_float += 4; from16 += 2;
- }
- break;
- case 1:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
- to_float[3] = 1.0;
- to_float += 4; from16++;
- }
- break;
- }
- }
- else {
- imb_addrectImBuf(ibuf);
-
- pixels = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(unsigned char), "pixels");
- if (pixels == NULL || ibuf->rect == NULL) {
- printf("Cannot allocate pixels array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* allocate memory for an array of row-pointers */
- row_pointers = (png_bytepp) MEM_mallocN((size_t)ibuf->y * sizeof(png_bytep), "row_pointers");
- if (row_pointers == NULL) {
- printf("Cannot allocate row-pointers array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* set the individual row-pointers to point at the correct offsets */
- for (int i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned char *)pixels + (((size_t)i) * ibuf->x) * channels * sizeof(unsigned char));
- }
-
- png_read_image(png_ptr, row_pointers);
-
- /* copy image data */
-
- to = (unsigned char *) ibuf->rect;
- from = pixels;
-
- switch (channels) {
- case 4:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = from[3];
- to += 4; from += 4;
- }
- break;
- case 3:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = 0xff;
- to += 4; from += 3;
- }
- break;
- case 2:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = to[1] = to[2] = from[0];
- to[3] = from[1];
- to += 4; from += 2;
- }
- break;
- case 1:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = to[1] = to[2] = from[0];
- to[3] = 0xff;
- to += 4; from++;
- }
- break;
- }
- }
-
- if (flags & IB_metadata) {
- png_text *text_chunks;
- int count = png_get_text(png_ptr, info_ptr, &text_chunks, NULL);
- IMB_metadata_ensure(&ibuf->metadata);
- for (int i = 0; i < count; i++) {
- IMB_metadata_set_field(ibuf->metadata, text_chunks[i].key, text_chunks[i].text);
- ibuf->flags |= IB_metadata;
- }
- }
-
- png_read_end(png_ptr, info_ptr);
- }
-
- /* clean up */
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- if (row_pointers)
- MEM_freeN(row_pointers);
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
-
- return(ibuf);
+ struct ImBuf *ibuf = NULL;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ unsigned char *pixels = NULL;
+ unsigned short *pixels16 = NULL;
+ png_bytepp row_pointers = NULL;
+ png_uint_32 width, height;
+ int bit_depth, color_type;
+ PNGReadStruct ps;
+
+ unsigned char *from, *to;
+ unsigned short *from16;
+ float *to_float;
+ unsigned int channels;
+
+ if (imb_is_a_png(mem) == 0)
+ return (NULL);
+
+ /* both 8 and 16 bit PNGs are default to standard byte colorspace */
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (png_ptr == NULL) {
+ printf("Cannot png_create_read_struct\n");
+ return NULL;
+ }
+
+ png_set_error_fn(png_ptr, NULL, imb_png_error, imb_png_warning);
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ printf("Cannot png_create_info_struct\n");
+ return NULL;
+ }
+
+ ps.size = size; /* XXX, 4gig limit! */
+ ps.data = mem;
+ ps.seek = 0;
+
+ png_set_read_fn(png_ptr, (void *)&ps, ReadData);
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ if (row_pointers)
+ MEM_freeN(row_pointers);
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+ return NULL;
+ }
+
+ // png_set_sig_bytes(png_ptr, 8);
+
+ png_read_info(png_ptr, info_ptr);
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
+
+ channels = png_get_channels(png_ptr, info_ptr);
+
+ switch (color_type) {
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ png_set_palette_to_rgb(png_ptr);
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ channels = 4;
+ }
+ else {
+ channels = 3;
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ if (bit_depth < 8) {
+ png_set_expand(png_ptr);
+ bit_depth = 8;
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ /* PNG_COLOR_TYPE_GRAY may also have alpha 'values', like with palette. */
+ channels = 2;
+ }
+ }
+ break;
+ default:
+ printf("PNG format not supported\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ ibuf = IMB_allocImBuf(width, height, 8 * channels, 0);
+
+ if (ibuf) {
+ ibuf->ftype = IMB_FTYPE_PNG;
+ if (bit_depth == 16)
+ ibuf->foptions.flag |= PNG_16BIT;
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
+ int unit_type;
+ png_uint_32 xres, yres;
+
+ if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) {
+ if (unit_type == PNG_RESOLUTION_METER) {
+ ibuf->ppm[0] = xres;
+ ibuf->ppm[1] = yres;
+ }
+ }
+ }
+ }
+ else {
+ printf("Couldn't allocate memory for PNG image\n");
+ }
+
+ if (ibuf && ((flags & IB_test) == 0)) {
+ if (bit_depth == 16) {
+ imb_addrectfloatImBuf(ibuf);
+ png_set_swap(png_ptr);
+
+ pixels16 = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(png_uint_16), "pixels");
+ if (pixels16 == NULL || ibuf->rect_float == NULL) {
+ printf("Cannot allocate pixels array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* allocate memory for an array of row-pointers */
+ row_pointers = (png_bytepp)MEM_mallocN((size_t)ibuf->y * sizeof(png_uint_16p),
+ "row_pointers");
+ if (row_pointers == NULL) {
+ printf("Cannot allocate row-pointers array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* set the individual row-pointers to point at the correct offsets */
+ for (size_t i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)((png_uint_16 *)pixels16 +
+ (i * ibuf->x) * channels);
+ }
+
+ png_read_image(png_ptr, row_pointers);
+
+ /* copy image data */
+
+ to_float = ibuf->rect_float;
+ from16 = pixels16;
+
+ switch (channels) {
+ case 4:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = from16[0] / 65535.0;
+ to_float[1] = from16[1] / 65535.0;
+ to_float[2] = from16[2] / 65535.0;
+ to_float[3] = from16[3] / 65535.0;
+ to_float += 4;
+ from16 += 4;
+ }
+ break;
+ case 3:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = from16[0] / 65535.0;
+ to_float[1] = from16[1] / 65535.0;
+ to_float[2] = from16[2] / 65535.0;
+ to_float[3] = 1.0;
+ to_float += 4;
+ from16 += 3;
+ }
+ break;
+ case 2:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
+ to_float[3] = from16[1] / 65535.0;
+ to_float += 4;
+ from16 += 2;
+ }
+ break;
+ case 1:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
+ to_float[3] = 1.0;
+ to_float += 4;
+ from16++;
+ }
+ break;
+ }
+ }
+ else {
+ imb_addrectImBuf(ibuf);
+
+ pixels = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(unsigned char), "pixels");
+ if (pixels == NULL || ibuf->rect == NULL) {
+ printf("Cannot allocate pixels array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* allocate memory for an array of row-pointers */
+ row_pointers = (png_bytepp)MEM_mallocN((size_t)ibuf->y * sizeof(png_bytep), "row_pointers");
+ if (row_pointers == NULL) {
+ printf("Cannot allocate row-pointers array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* set the individual row-pointers to point at the correct offsets */
+ for (int i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)(
+ (unsigned char *)pixels + (((size_t)i) * ibuf->x) * channels * sizeof(unsigned char));
+ }
+
+ png_read_image(png_ptr, row_pointers);
+
+ /* copy image data */
+
+ to = (unsigned char *)ibuf->rect;
+ from = pixels;
+
+ switch (channels) {
+ case 4:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+ to += 4;
+ from += 4;
+ }
+ break;
+ case 3:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = 0xff;
+ to += 4;
+ from += 3;
+ }
+ break;
+ case 2:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = to[1] = to[2] = from[0];
+ to[3] = from[1];
+ to += 4;
+ from += 2;
+ }
+ break;
+ case 1:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = to[1] = to[2] = from[0];
+ to[3] = 0xff;
+ to += 4;
+ from++;
+ }
+ break;
+ }
+ }
+
+ if (flags & IB_metadata) {
+ png_text *text_chunks;
+ int count = png_get_text(png_ptr, info_ptr, &text_chunks, NULL);
+ IMB_metadata_ensure(&ibuf->metadata);
+ for (int i = 0; i < count; i++) {
+ IMB_metadata_set_field(ibuf->metadata, text_chunks[i].key, text_chunks[i].text);
+ ibuf->flags |= IB_metadata;
+ }
+ }
+
+ png_read_end(png_ptr, info_ptr);
+ }
+
+ /* clean up */
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ if (row_pointers)
+ MEM_freeN(row_pointers);
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+
+ return (ibuf);
}