commit 5bb4be011b6d2857466a2730bb208cad6b839133
parent 1c801ebeaacd92d08b0225dd7e8c8e7963aa59d8
Author: FRIGN <dev@frign.de>
Date: Mon, 4 Jan 2016 17:31:10 +0100
png2ff: Convert 16-Bit PNG's losslessly
It took me quite a while to figure out that libpng already gives you
big endian values.
I also tweaked the library functions a bit more to really make sure
that all PNG-types (grayscale, palette, ...) are converted to RGBA
properly.
Diffstat:
M | png2ff.c | | | 36 | ++++++++++++++++++++++++++---------- |
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/png2ff.c b/png2ff.c
@@ -32,10 +32,14 @@ main(int argc, char *argv[])
return 1;
}
png_init_io(png_struct_p, stdin);
- png_set_add_alpha(png_struct_p, 255, PNG_FILLER_AFTER);
+ if (png_get_valid(png_struct_p, png_info_p, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_struct_p);
+ png_set_add_alpha(png_struct_p, 255*257, PNG_FILLER_AFTER);
+ png_set_expand_gray_1_2_4_to_8(png_struct_p);
png_set_gray_to_rgb(png_struct_p);
- png_read_png(png_struct_p, png_info_p, PNG_TRANSFORM_STRIP_16 |
- PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);
+ png_set_packing(png_struct_p);
+ png_read_png(png_struct_p, png_info_p, PNG_TRANSFORM_PACKING |
+ PNG_TRANSFORM_EXPAND, NULL);
png_get_IHDR(png_struct_p, png_info_p, &width, &height, &depth,
&color, &interlace, NULL, NULL);
png_row_len = png_get_rowbytes(png_struct_p, png_info_p);
@@ -49,16 +53,28 @@ main(int argc, char *argv[])
fwrite(&tmp32, sizeof(uint32_t), 1, stdout);
/* write data */
- /* TODO: allow 16 bit PNGs to be converted losslessly */
- for (r = 0; r < height; ++r) {
- for (i = 0; i < png_row_len; i++) {
- /* ((2^16-1) / 255) == 257 */
- tmp16 = htons(257 * png_row_p[r][i]);
- fwrite(&tmp16, sizeof(uint16_t), 1, stdout);
+ if (depth == 8) {
+ for (r = 0; r < height; ++r) {
+ for (i = 0; i < png_row_len; i++) {
+ /* ((2^16-1) / 255) == 257 */
+ tmp16 = htons(257 * png_row_p[r][i]);
+ fwrite(&tmp16, sizeof(uint16_t), 1, stdout);
+ }
}
+ } else if (depth == 16) {
+ for (r = 0; r < height; ++r) {
+ for (i = 0; i < png_row_len / 2; i++) {
+ tmp16 = *((uint16_t *)
+ (png_row_p[r] + 2 * i));
+ fwrite(&tmp16, sizeof(uint16_t), 1, stdout);
+ }
+ }
+ fprintf(stderr, "written r=%d, i=%d\n", r, i);
+ } else {
+ fprintf(stderr, "format error\n");
+ return 1;
}
- /* cleanup */
png_destroy_read_struct(&png_struct_p, &png_info_p, NULL);
return 0;