[hackers] [farbfeld] png2ff: Convert 16-Bit PNG's losslessly || FRIGN
commit 5bb4be011b6d2857466a2730bb208cad6b839133
Author: FRIGN <dev_AT_frign.de>
AuthorDate: Mon Jan 4 17:31:10 2016 +0100
Commit: FRIGN <dev_AT_frign.de>
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
_AT_@ -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);
_AT_@ -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;
Received on Mon Jan 04 2016 - 17:46:01 CET
This archive was generated by hypermail 2.3.0
: Mon Jan 04 2016 - 17:48:13 CET