6 gcc convert_argb_png.c -o convert_argb_png -lpng -ljpeg
8 this tool takes a 32bit RGB+A PNG file, for example produced by photoshop,
9 and splits the data into RGB and A. The RGB data is then lossy compressed with JPEG,
10 the alpha channel is lossless compressed as PNG.
12 enigma2 can then pickup those two files, and combine them on load. This gives
13 the possibilty to use truecolor RGB pictures without storing them lossless
14 (which would be inefficient).
23 int main(int argc, char **argv)
27 fprintf(stderr, "usage: %s <input.png> <output_basename> <jpeg-quality>\n", *argv);
31 const char *infile = argv[1];
32 const char *outfile = argv[2];
33 int jpeg_quality = atoi(argv[3]);
35 FILE *fpin = fopen(infile, "rb");
42 unsigned char header[8];
43 fread(header, 1, 8, fpin);
44 if (png_sig_cmp(header, 0, 8))
46 fprintf(stderr, "this is not a PNG file\n");
49 png_structp png_ptr = png_create_read_struct
50 (PNG_LIBPNG_VER_STRING, 0, 0, 0);
53 png_infop info_ptr = png_create_info_struct(png_ptr);
56 png_infop end_info = png_create_info_struct(png_ptr);
59 if (setjmp(png_jmpbuf(png_ptr)))
61 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
63 fprintf(stderr, "failed.\n");
67 png_init_io(png_ptr, fpin);
68 png_set_sig_bytes(png_ptr, 8);
69 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0);
70 png_bytep * row_pointers = png_get_rows(png_ptr, info_ptr);
72 png_uint_32 width, height;
73 int bit_depth, color_type;
74 png_get_IHDR(png_ptr, info_ptr, &width, &height,
75 &bit_depth, &color_type, 0, 0, 0);
77 if (color_type != PNG_COLOR_TYPE_RGB_ALPHA)
79 fprintf(stderr, "input PNG must be RGB+Alpha\n");
84 fprintf(stderr, "input bit depth must be 8bit!\n");
87 printf("png is %ldx%ld\n", width, height);
88 int channels = png_get_channels(png_ptr, info_ptr);
91 fprintf(stderr, "channels must be 4.\n");
96 struct jpeg_compress_struct cinfo;
97 struct jpeg_error_mgr jerr;
98 JSAMPROW jrow_pointer[1];
101 char filename[strlen(outfile) + 10];
102 strcpy(filename, outfile);
103 strcat(filename, ".rgb.jpg");
105 outfp = fopen(filename, "wb");
112 cinfo.err = jpeg_std_error(&jerr);
113 jpeg_create_compress(&cinfo);
114 jpeg_stdio_dest(&cinfo, outfp);
116 cinfo.image_width = width;
117 cinfo.image_height = height;
118 cinfo.input_components = 3;
119 cinfo.in_color_space = JCS_RGB;
120 jpeg_set_defaults(&cinfo);
121 jpeg_set_quality(&cinfo, jpeg_quality, 1);
122 jpeg_start_compress(&cinfo, 1);
124 unsigned char *row = malloc(width * 3);
125 while (cinfo.next_scanline < cinfo.image_height)
128 jrow_pointer[0] = row;
129 unsigned char *source = row_pointers[cinfo.next_scanline];
130 for (x = 0; x < width; ++x)
132 row[x * 3 + 0] = source[0];
133 row[x * 3 + 1] = source[1];
134 row[x * 3 + 2] = source[2];
137 jpeg_write_scanlines(&cinfo, jrow_pointer, 1);
140 jpeg_finish_compress(&cinfo);
142 jpeg_destroy_compress(&cinfo);
145 strcpy(filename, outfile);
146 strcat(filename, ".a.png");
148 outfp = fopen(filename, "wb");
155 png_structp png_ptr_w = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
156 png_infop info_ptr_w = png_create_info_struct(png_ptr_w);
157 if (setjmp(png_jmpbuf(png_ptr_w)))
159 png_destroy_write_struct(&png_ptr_w, &info_ptr_w);
163 png_init_io(png_ptr_w, outfp);
164 png_set_IHDR(png_ptr_w, info_ptr_w, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
166 /* turn RGBA into A, in-place */
168 for (y=0; y < height; ++y)
170 unsigned char *source = row_pointers[y];
171 unsigned char *dst = source;
172 for (x=0; x < width; ++x)
178 png_set_rows(png_ptr_w, info_ptr_w, row_pointers);
179 png_write_png(png_ptr_w, info_ptr_w, PNG_TRANSFORM_IDENTITY, 0);
180 png_write_end(png_ptr_w, info_ptr_w);
181 png_destroy_write_struct(&png_ptr_w, &info_ptr_w);