diff --git a/png.h b/png.h index 4a0835912..61c92d48e 100644 --- a/png.h +++ b/png.h @@ -2684,7 +2684,7 @@ typedef struct * The channels are encoded in one of two ways: * * a) As a small integer, value 0..255, contained in a (png_byte). For the - * alpha channel the original value is simple value/255. For the color or + * alpha channel the original value is simply value/255. For the color or * luminance channels the value is encoded according to the sRGB specification * and matches the 8-bit format expected by typical display devices. * @@ -2742,7 +2742,7 @@ typedef struct */ #define PNG_FORMAT_GRAY 0 #define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA -#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_AFIRST) +#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) #define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR #define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) #define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) @@ -2755,11 +2755,11 @@ typedef struct * always the same - there is no provision for swapping the order of the * components in the linear format. */ -#define PNG_FORMAT_FP_Y PNG_FORMAT_FLAG_FP -#define PNG_FORMAT_FP_Y_ALPHA (PNG_FORMAT_FLAG_FP|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_FP_RGB (PNG_FORMAT_FLAG_FP|PNG_FORMAT_FLAG_COLOR) -#define PNG_FORMAT_FP_RGB_ALPHA \ - (PNG_FORMAT_FLAG_FP|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR +#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) +#define PNG_FORMAT_LINEAR_RGB_ALPHA \ + (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) /* PNG_IMAGE macros * @@ -2828,7 +2828,7 @@ PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, /* Finish reading the image into the supplied buffer and clean up the * png_image structure. * - * row_stride is the step, in png_byte or float units as appropriate, + * row_stride is the step, in png_byte or png_uint_16 units as appropriate, * between adjacent rows. A positive stride indicates that the top-most row * is first in the buffer - the normal top-down arrangement. A negative * stride indicates that the bottom-most row is first in the buffer. diff --git a/pngwrite.c b/pngwrite.c index 8050fba99..594e8e3d5 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1973,18 +1973,26 @@ png_image_write_main(png_voidp argument) { /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); - png_set_cHRM_fixed(png_ptr, info_ptr, - /* color x y */ - /* white */ 31270, 32900, - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000 - ); + + if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB)) + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000 + ); } - else + else if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB)) png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); + /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit + * space must still be gamma encoded. + */ + else + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); + /* Write the file header. */ png_write_info(png_ptr, info_ptr); @@ -2081,7 +2089,7 @@ png_image_write_main(png_voidp argument) } int PNGAPI -png_image_write_to_stdio (png_imagep image, FILE *file, int convert_to_8bit, +png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, const void *buffer, png_int_32 row_stride) { /* Write the image to the given (FILE*). */ @@ -2125,7 +2133,7 @@ png_image_write_to_stdio (png_imagep image, FILE *file, int convert_to_8bit, } int PNGAPI -png_image_write_to_file (png_imagep image, const char *file_name, +png_image_write_to_file(png_imagep image, const char *file_name, int convert_to_8bit, const void *buffer, png_int_32 row_stride) { /* Write the image to the named file. */ @@ -2137,56 +2145,38 @@ png_image_write_to_file (png_imagep image, const char *file_name, if (fp != NULL) { - if (png_image_write_init(image)) + if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, + row_stride)) { - png_image_write_control display; + int error; /* from fflush/fclose */ - image->opaque->png_ptr->io_ptr = fp; - image->opaque->owned_file = 1; - /* No need to close this file now - png_image_free will do that. - */ - - memset(&display, 0, sizeof display); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.convert_to_8bit = convert_to_8bit; - - if (png_safe_execute(image, png_image_write_main, &display)) + /* Make sure the file is flushed correctly. */ + if (fflush(fp) == 0 && ferror(fp) == 0) { - int error; /* from fflush/fclose */ + if (fclose(fp) == 0) + return 1; - /* Make sure the file is flushed correctly. */ - if (fflush(fp) == 0) - { - /* Steal the file pointer back to make sure it closes ok. - */ - image->opaque->png_ptr->io_ptr = NULL; - image->opaque->owned_file = 0; - - if (fclose(fp) == 0) - { - png_image_free(image); - return 1; - } - - error = errno; - } - - else - error = errno; - - return png_image_error(image, strerror(error)); + error = errno; /* from fclose */ } - else /* else cleanup has already happened */ - return 0; + else + { + error = errno; /* from fflush or ferror */ + (void)fclose(fp); + } + + (void)remove(file_name); + /* The image has already been cleaned up; this is just used to + * set the error (because the original write succeeded). + */ + return png_image_error(image, strerror(error)); } else { /* Clean up: just the opened file. */ (void)fclose(fp); + (void)remove(file_name); return 0; } }