commit 5bb4be011b6d2857466a2730bb208cad6b839133
Author:     FRIGN <[email protected]>
AuthorDate: Mon Jan 4 17:31:10 2016 +0100
Commit:     FRIGN <[email protected]>
CommitDate: Mon Jan 4 17:31:10 2016 +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.

diff --git a/png2ff.c b/png2ff.c
index e42149d..9f77344 100644
--- 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;

Reply via email to