Exemplo n.º 1
0
/* does no zbuffers? */
ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
{
    ImBuf *ibuf2, tbuf;
    int flags = 0;
    int a, x, y;

    if (ibuf1 == NULL) return NULL;

    if (ibuf1->rect) flags |= IB_rect;
    if (ibuf1->rect_float) flags |= IB_rectfloat;

    x = ibuf1->x;
    y = ibuf1->y;
    if (ibuf1->flags & IB_fields) y *= 2;

    ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
    if (ibuf2 == NULL) return NULL;

    if (flags & IB_rect)
        memcpy(ibuf2->rect, ibuf1->rect, x * y * sizeof(int));

    if (flags & IB_rectfloat)
        memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels * x * y * sizeof(float));

    if (ibuf1->encodedbuffer) {
        ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
        if (imb_addencodedbufferImBuf(ibuf2) == false) {
            IMB_freeImBuf(ibuf2);
            return NULL;
        }

        memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
    }

    /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
    tbuf = *ibuf1;

    /* fix pointers */
    tbuf.rect          = ibuf2->rect;
    tbuf.rect_float    = ibuf2->rect_float;
    tbuf.encodedbuffer = ibuf2->encodedbuffer;
    tbuf.zbuf          = NULL;
    tbuf.zbuf_float    = NULL;
    for (a = 0; a < IB_MIPMAP_LEVELS; a++)
        tbuf.mipmap[a] = NULL;
    tbuf.dds_data.data = NULL;

    /* set malloc flag */
    tbuf.mall               = ibuf2->mall;
    tbuf.c_handle           = NULL;
    tbuf.refcounter         = 0;

    /* for now don't duplicate metadata */
    tbuf.metadata = NULL;

    tbuf.display_buffer_flags = NULL;
    tbuf.colormanage_cache = NULL;

    *ibuf2 = tbuf;

    return(ibuf2);
}
Exemplo n.º 2
0
Arquivo: png.c Projeto: jinjoh/NOOR
short imb_savepng(struct ImBuf *ibuf, char *name, int flags)
{
    png_structp png_ptr;
    png_infop info_ptr;

    unsigned char *pixels = 0;
    unsigned char *from, *to;
    png_bytepp row_pointers = 0;
    int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
    FILE *fp = 0;

    bytesperpixel = (ibuf->depth + 7) >> 3;
    if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
        printf("imb_savepng: unsupported bytes per pixel: %d\n", bytesperpixel);
        return (0);
    }

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                      NULL, NULL, NULL);
    if (png_ptr == NULL) {
        printf("Cannot png_create_write_struct\n");
        return 0;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
        printf("Cannot png_create_info_struct\n");
        return 0;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        if (pixels) MEM_freeN(pixels);
        if (row_pointers) MEM_freeN(row_pointers);
        // printf("Aborting\n");
        if (fp) {
            fflush(fp);
            fclose(fp);
        }
        return 0;
    }

    // copy image data

    pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "pixels");
    if (pixels == NULL) {
        printf("Cannot allocate pixels array\n");
        return 0;
    }

    from = (unsigned char *) ibuf->rect;
    to = pixels;

    switch (bytesperpixel) {
    case 4:
        color_type = PNG_COLOR_TYPE_RGBA;
        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;
        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;
        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 = fopen(name, "wb");
        if (!fp) {
            MEM_freeN(pixels);
            return 0;
        }
        png_init_io(png_ptr, fp);
    }

    /*
    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_compression_level(png_ptr, Z_BEST_COMPRESSION);
    */

    // png image settings
    png_set_IHDR(png_ptr,
                 info_ptr,
                 ibuf->x,
                 ibuf->y,
                 8,
                 color_type,
                 PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);

    /* image text info */
    if (ibuf->img_info) {
        png_text*  imginfo;
        ImgInfo* iptr;
        int  num_text = 0;
        iptr = ibuf->img_info;
        while (iptr) {
            num_text++;
            iptr = iptr->next;
        }

        imginfo = MEM_callocN(num_text*sizeof(png_text), "png_imginfo");
        iptr = ibuf->img_info;
        num_text = 0;
        while (iptr) {

            imginfo[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
            imginfo[num_text].key = iptr->key;
            imginfo[num_text].text = iptr->value;
            num_text++;
            iptr = iptr->next;
        }

        png_set_text(png_ptr, info_ptr, imginfo, num_text);
        MEM_freeN(imginfo);

    }

    // write the file header information
    png_write_info(png_ptr, info_ptr);

    // 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("Cannot allocate row-pointers array\n");
        MEM_freeN(pixels);
        return 0;
    }

    // set the individual row-pointers to point at the correct offsets
    for (i = 0; i < ibuf->y; i++) {
        row_pointers[ibuf->y-1-i] = (png_bytep)
                                    ((unsigned char *)pixels + (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
    MEM_freeN(pixels);
    MEM_freeN(row_pointers);
    png_destroy_write_struct(&png_ptr, &info_ptr);

    if (fp) {
        fflush(fp);
        fclose(fp);
    }

    return(1);
}
Exemplo n.º 3
0
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;

	int is_16bit = (ibuf->ftype & PNG_16BIT) && ibuf->rect_float;

	/* use the jpeg quality setting for compression */
	int compression;
	compression = (int)(((float)(ibuf->ftype & 0xff) / 11.1111f));
	compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);

	/* for prints */
	if (flags & IB_mem)
		name = "<memory>";

	bytesperpixel = (ibuf->planes + 7) >> 3;
	if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
		printf("imb_savepng: Cunsupported 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 */

	if (is_16bit)
		pixels16 = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned short), "png 16bit pixels");
	else
		pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * 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) {
				for (i = ibuf->x * ibuf->y; i > 0; i--) {
					premul_to_straight_v4(from_straight, from_float);
					to16[0] = FTOUSHORT(from_straight[0]);
					to16[1] = FTOUSHORT(from_straight[1]);
					to16[2] = FTOUSHORT(from_straight[2]);
					to16[3] = FTOUSHORT(from_straight[3]);
					to16 += 4; from_float += 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) {
				for (i = ibuf->x * ibuf->y; i > 0; i--) {
					premul_to_straight_v4(from_straight, from_float);
					to16[0] = FTOUSHORT(from_straight[0]);
					to16[1] = FTOUSHORT(from_straight[1]);
					to16[2] = FTOUSHORT(from_straight[2]);
					to16 += 3; from_float += 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) {
				for (i = ibuf->x * ibuf->y; i > 0; i--) {
					premul_to_straight_v4(from_straight, from_float);
					to16[0] = FTOUSHORT(from_straight[0]);
					to16++; from_float += 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);
#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;
		ImMetaData *iptr;
		int num_text = 0;
		iptr = ibuf->metadata;
		while (iptr) {
			num_text++;
			iptr = iptr->next;
		}
		
		metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata");
		iptr = ibuf->metadata;
		num_text = 0;
		while (iptr) {
			
			metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
			metadata[num_text].key = iptr->key;
			metadata[num_text].text = iptr->value;
			num_text++;
			iptr = iptr->next;
		}
		
		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);
#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 + (i * ibuf->x) * bytesperpixel);
		}
	}
	else {
		for (i = 0; i < ibuf->y; i++) {
			row_pointers[ibuf->y - 1 - i] = (png_bytep)
			                                ((unsigned char *)pixels + (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);
}
Exemplo n.º 4
0
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);
	}

#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);
#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);

#ifdef __LITTLE_ENDIAN__
	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);
}