From: Felix Domke Date: Wed, 12 Dec 2007 16:26:10 +0000 (+0000) Subject: add tool to convert 32bit argb into jpg+png. we still need enigma support to load... X-Git-Tag: 2.6.0~1673 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/ec31699b6d93ec8b9b30775eab66351260afdf37 add tool to convert 32bit argb into jpg+png. we still need enigma support to load them. --- diff --git a/tools/convert_argb_png.c b/tools/convert_argb_png.c new file mode 100644 index 00000000..d278ca95 --- /dev/null +++ b/tools/convert_argb_png.c @@ -0,0 +1,183 @@ +/* + convert_argb_png.c + + compile with: + + gcc convert_argb_png.c -o convert_argb_png -lpng -ljpeg + + this tool takes a 32bit RGB+A PNG file, for example produced by photoshop, + and splits the data into RGB and A. The RGB data is then lossy compressed with JPEG, + the alpha channel is lossless compressed as PNG. + + enigma2 can then pickup those two files, and combine them on load. This gives + the possibilty to use truecolor RGB pictures without storing them lossless + (which would be inefficient). + */ + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + if (argc != 4) + { + fprintf(stderr, "usage: %s \n", *argv); + return 1; + } + + const char *infile = argv[1]; + const char *outfile = argv[2]; + int jpeg_quality = atoi(argv[3]); + + FILE *fpin = fopen(infile, "rb"); + if (!fpin) + { + perror(infile); + return 1; + } + + unsigned char header[8]; + fread(header, 1, 8, fpin); + if (png_sig_cmp(header, 0, 8)) + { + fprintf(stderr, "this is not a PNG file\n"); + return 1; + } + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, 0, 0, 0); + assert(png_ptr); + + png_infop info_ptr = png_create_info_struct(png_ptr); + assert(info_ptr); + + png_infop end_info = png_create_info_struct(png_ptr); + assert (end_info); + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fpin); + fprintf(stderr, "failed.\n"); + return 1; + } + + png_init_io(png_ptr, fpin); + png_set_sig_bytes(png_ptr, 8); + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0); + png_bytep * row_pointers = png_get_rows(png_ptr, info_ptr); + + png_uint_32 width, height; + int bit_depth, color_type; + png_get_IHDR(png_ptr, info_ptr, &width, &height, + &bit_depth, &color_type, 0, 0, 0); + + if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) + { + fprintf(stderr, "input PNG must be RGB+Alpha\n"); + return 1; + } + if (bit_depth != 8) + { + fprintf(stderr, "input bit depth must be 8bit!\n"); + return 1; + } + printf("png is %ldx%ld\n", width, height); + int channels = png_get_channels(png_ptr, info_ptr); + if (channels != 4) + { + fprintf(stderr, "channels must be 4.\n"); + return 1; + } + + /* now write jpeg */ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPROW jrow_pointer[1]; + FILE *outfp; + + char filename[strlen(outfile) + 10]; + strcpy(filename, outfile); + strcat(filename, ".rgb.jpg"); + + outfp = fopen(filename, "wb"); + if (!outfp) + { + perror(filename); + return 1; + } + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, outfp); + + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, jpeg_quality, 1); + jpeg_start_compress(&cinfo, 1); + + unsigned char *row = malloc(width * 3); + while (cinfo.next_scanline < cinfo.image_height) + { + int x; + jrow_pointer[0] = row; + unsigned char *source = row_pointers[cinfo.next_scanline]; + for (x = 0; x < width; ++x) + { + row[x * 3 + 0] = source[0]; + row[x * 3 + 1] = source[1]; + row[x * 3 + 2] = source[2]; + source += 4; + } + jpeg_write_scanlines(&cinfo, jrow_pointer, 1); + } + + jpeg_finish_compress(&cinfo); + fclose(outfp); + jpeg_destroy_compress(&cinfo); + + /* and write png */ + strcpy(filename, outfile); + strcat(filename, ".a.png"); + + outfp = fopen(filename, "wb"); + if (!outfp) + { + perror(filename); + return 1; + } + + png_structp png_ptr_w = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + png_infop info_ptr_w = png_create_info_struct(png_ptr_w); + if (setjmp(png_jmpbuf(png_ptr_w))) + { + png_destroy_write_struct(&png_ptr_w, &info_ptr_w); + fclose(outfp); + return 1; + } + png_init_io(png_ptr_w, outfp); + 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); + + /* turn RGBA into A, in-place */ + int x, y; + for (y=0; y < height; ++y) + { + unsigned char *source = row_pointers[y]; + unsigned char *dst = source; + for (x=0; x < width; ++x) + { + *dst++ = source[3]; + source += 4; + } + } + png_set_rows(png_ptr_w, info_ptr_w, row_pointers); + png_write_png(png_ptr_w, info_ptr_w, PNG_TRANSFORM_IDENTITY, 0); + png_write_end(png_ptr_w, info_ptr_w); + png_destroy_write_struct(&png_ptr_w, &info_ptr_w); + return 0; +}