summaryrefslogtreecommitdiff
path: root/png2ff.c
diff options
context:
space:
mode:
authorFRIGN <dev@frign.de>2016-01-04 17:31:10 +0100
committerFRIGN <dev@frign.de>2016-01-04 17:31:10 +0100
commit5bb4be011b6d2857466a2730bb208cad6b839133 (patch)
tree7aa88dda95d05159659c35dec3856da86be2a3ce /png2ff.c
parent1c801ebeaacd92d08b0225dd7e8c8e7963aa59d8 (diff)
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 (limited to 'png2ff.c')
-rw-r--r--png2ff.c36
1 files changed, 26 insertions, 10 deletions
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;