mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 10:25:46 +01:00 
			
		
		
		
	cwebp: extract png decoding to its own module
Change-Id: I80dd09fe1f1c6317e9d0cdd422438bda11b43ed5
This commit is contained in:
		| @@ -171,6 +171,9 @@ DSP_OBJS = \ | ||||
|     $(DIROBJ)\dsp\upsampling_sse2.obj \ | ||||
|     $(DIROBJ)\dsp\yuv.obj \ | ||||
|  | ||||
| EX_FORMAT_DEC_OBJS = \ | ||||
|     $(DIROBJ)\examples/pngdec.obj \ | ||||
|  | ||||
| EX_UTIL_OBJS = \ | ||||
|     $(DIROBJ)\examples\example_util.obj \ | ||||
|  | ||||
| @@ -218,7 +221,7 @@ OUT_LIBS = $(LIBWEBP) | ||||
| OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe | ||||
|  | ||||
| all: $(OUT_LIBS) $(OUT_EXAMPLES) | ||||
| $(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj | ||||
| $(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(EX_FORMAT_DEC_OBJS) | ||||
| $(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj | ||||
| $(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX) | ||||
| $(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(LIBWEBP) | ||||
|   | ||||
| @@ -21,6 +21,7 @@ dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES) | ||||
| dwebp_LDADD = libexampleutil.la ../src/libwebp.la $(PNG_LIBS) $(JPEG_LIBS) | ||||
|  | ||||
| cwebp_SOURCES  = cwebp.c metadata.h stopwatch.h | ||||
| cwebp_SOURCES += pngdec.c pngdec.h | ||||
| cwebp_CPPFLAGS  = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) | ||||
| cwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES) | ||||
| cwebp_LDADD = ../src/libwebp.la $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS) | ||||
|   | ||||
							
								
								
									
										107
									
								
								examples/cwebp.c
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								examples/cwebp.c
									
									
									
									
									
								
							| @@ -18,12 +18,8 @@ | ||||
| #include "config.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef WEBP_HAVE_PNG | ||||
| #include <png.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef WEBP_HAVE_JPEG | ||||
| #include <setjmp.h>   // note: this must be included *after* png.h | ||||
| #include <setjmp.h> | ||||
| #include <jpeglib.h> | ||||
| #endif | ||||
|  | ||||
| @@ -47,6 +43,7 @@ | ||||
|  | ||||
| #include "webp/encode.h" | ||||
| #include "./metadata.h" | ||||
| #include "./pngdec.h" | ||||
| #include "./stopwatch.h" | ||||
| #ifndef WEBP_DLL | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| @@ -388,106 +385,6 @@ static int ReadJPEG(FILE* in_file, WebPPicture* const pic) { | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifdef WEBP_HAVE_PNG | ||||
| static void PNGAPI error_function(png_structp png, png_const_charp dummy) { | ||||
|   (void)dummy;  // remove variable-unused warning | ||||
|   longjmp(png_jmpbuf(png), 1); | ||||
| } | ||||
|  | ||||
| static int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) { | ||||
|   png_structp png; | ||||
|   png_infop info; | ||||
|   int color_type, bit_depth, interlaced; | ||||
|   int has_alpha; | ||||
|   int num_passes; | ||||
|   int p; | ||||
|   int ok = 0; | ||||
|   png_uint_32 width, height, y; | ||||
|   int stride; | ||||
|   uint8_t* rgb = NULL; | ||||
|  | ||||
|   png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); | ||||
|   if (png == NULL) { | ||||
|     goto End; | ||||
|   } | ||||
|  | ||||
|   png_set_error_fn(png, 0, error_function, NULL); | ||||
|   if (setjmp(png_jmpbuf(png))) { | ||||
|  Error: | ||||
|     png_destroy_read_struct(&png, NULL, NULL); | ||||
|     free(rgb); | ||||
|     goto End; | ||||
|   } | ||||
|  | ||||
|   info = png_create_info_struct(png); | ||||
|   if (info == NULL) goto Error; | ||||
|  | ||||
|   png_init_io(png, in_file); | ||||
|   png_read_info(png, info); | ||||
|   if (!png_get_IHDR(png, info, | ||||
|                     &width, &height, &bit_depth, &color_type, &interlaced, | ||||
|                     NULL, NULL)) goto Error; | ||||
|  | ||||
|   png_set_strip_16(png); | ||||
|   png_set_packing(png); | ||||
|   if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); | ||||
|   if (color_type == PNG_COLOR_TYPE_GRAY || | ||||
|       color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { | ||||
|     if (bit_depth < 8) { | ||||
|       png_set_expand_gray_1_2_4_to_8(png); | ||||
|     } | ||||
|     png_set_gray_to_rgb(png); | ||||
|   } | ||||
|   if (png_get_valid(png, info, PNG_INFO_tRNS)) { | ||||
|     png_set_tRNS_to_alpha(png); | ||||
|     has_alpha = 1; | ||||
|   } else { | ||||
|     has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA); | ||||
|   } | ||||
|  | ||||
|   if (!keep_alpha) { | ||||
|     png_set_strip_alpha(png); | ||||
|     has_alpha = 0; | ||||
|   } | ||||
|  | ||||
|   num_passes = png_set_interlace_handling(png); | ||||
|   png_read_update_info(png, info); | ||||
|   stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb); | ||||
|   rgb = (uint8_t*)malloc(stride * height); | ||||
|   if (rgb == NULL) goto Error; | ||||
|   for (p = 0; p < num_passes; ++p) { | ||||
|     for (y = 0; y < height; ++y) { | ||||
|       png_bytep row = rgb + y * stride; | ||||
|       png_read_rows(png, &row, NULL, 1); | ||||
|     } | ||||
|   } | ||||
|   png_read_end(png, info); | ||||
|   png_destroy_read_struct(&png, &info, NULL); | ||||
|  | ||||
|   pic->width = width; | ||||
|   pic->height = height; | ||||
|   ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride) | ||||
|                  : WebPPictureImportRGB(pic, rgb, stride); | ||||
|   free(rgb); | ||||
|  | ||||
|   if (ok && has_alpha && keep_alpha == 2) { | ||||
|     WebPCleanupTransparentArea(pic); | ||||
|   } | ||||
|  | ||||
|  End: | ||||
|   return ok; | ||||
| } | ||||
| #else | ||||
| static int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) { | ||||
|   (void)in_file; | ||||
|   (void)pic; | ||||
|   (void)keep_alpha; | ||||
|   fprintf(stderr, "PNG support not compiled. Please install the libpng " | ||||
|           "development package before building.\n"); | ||||
|   return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifdef WEBP_HAVE_TIFF | ||||
| static int ReadTIFF(const char* const filename, | ||||
|                     WebPPicture* const pic, int keep_alpha) { | ||||
|   | ||||
							
								
								
									
										124
									
								
								examples/pngdec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								examples/pngdec.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| // Copyright 2012 Google Inc. All Rights Reserved. | ||||
| // | ||||
| // This code is licensed under the same terms as WebM: | ||||
| //  Software License Agreement:  http://www.webmproject.org/license/software/ | ||||
| //  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/ | ||||
| // ----------------------------------------------------------------------------- | ||||
| // | ||||
| // PNG decode. | ||||
|  | ||||
| #include "./pngdec.h" | ||||
|  | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #include "config.h" | ||||
| #endif | ||||
|  | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef WEBP_HAVE_PNG | ||||
| #include <png.h> | ||||
| #include <setjmp.h>   // note: this must be included *after* png.h | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "webp/encode.h" | ||||
|  | ||||
| static void PNGAPI error_function(png_structp png, png_const_charp dummy) { | ||||
|   (void)dummy;  // remove variable-unused warning | ||||
|   longjmp(png_jmpbuf(png), 1); | ||||
| } | ||||
|  | ||||
| int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) { | ||||
|   png_structp png; | ||||
|   png_infop info; | ||||
|   int color_type, bit_depth, interlaced; | ||||
|   int has_alpha; | ||||
|   int num_passes; | ||||
|   int p; | ||||
|   int ok = 0; | ||||
|   png_uint_32 width, height, y; | ||||
|   int stride; | ||||
|   uint8_t* rgb = NULL; | ||||
|  | ||||
|   png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); | ||||
|   if (png == NULL) { | ||||
|     goto End; | ||||
|   } | ||||
|  | ||||
|   png_set_error_fn(png, 0, error_function, NULL); | ||||
|   if (setjmp(png_jmpbuf(png))) { | ||||
|  Error: | ||||
|     png_destroy_read_struct(&png, NULL, NULL); | ||||
|     free(rgb); | ||||
|     goto End; | ||||
|   } | ||||
|  | ||||
|   info = png_create_info_struct(png); | ||||
|   if (info == NULL) goto Error; | ||||
|  | ||||
|   png_init_io(png, in_file); | ||||
|   png_read_info(png, info); | ||||
|   if (!png_get_IHDR(png, info, | ||||
|                     &width, &height, &bit_depth, &color_type, &interlaced, | ||||
|                     NULL, NULL)) goto Error; | ||||
|  | ||||
|   png_set_strip_16(png); | ||||
|   png_set_packing(png); | ||||
|   if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); | ||||
|   if (color_type == PNG_COLOR_TYPE_GRAY || | ||||
|       color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { | ||||
|     if (bit_depth < 8) { | ||||
|       png_set_expand_gray_1_2_4_to_8(png); | ||||
|     } | ||||
|     png_set_gray_to_rgb(png); | ||||
|   } | ||||
|   if (png_get_valid(png, info, PNG_INFO_tRNS)) { | ||||
|     png_set_tRNS_to_alpha(png); | ||||
|     has_alpha = 1; | ||||
|   } else { | ||||
|     has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA); | ||||
|   } | ||||
|  | ||||
|   if (!keep_alpha) { | ||||
|     png_set_strip_alpha(png); | ||||
|     has_alpha = 0; | ||||
|   } | ||||
|  | ||||
|   num_passes = png_set_interlace_handling(png); | ||||
|   png_read_update_info(png, info); | ||||
|   stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb); | ||||
|   rgb = (uint8_t*)malloc(stride * height); | ||||
|   if (rgb == NULL) goto Error; | ||||
|   for (p = 0; p < num_passes; ++p) { | ||||
|     for (y = 0; y < height; ++y) { | ||||
|       png_bytep row = rgb + y * stride; | ||||
|       png_read_rows(png, &row, NULL, 1); | ||||
|     } | ||||
|   } | ||||
|   png_read_end(png, info); | ||||
|   png_destroy_read_struct(&png, &info, NULL); | ||||
|  | ||||
|   pic->width = width; | ||||
|   pic->height = height; | ||||
|   ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride) | ||||
|                  : WebPPictureImportRGB(pic, rgb, stride); | ||||
|   free(rgb); | ||||
|  | ||||
|   if (ok && has_alpha && keep_alpha == 2) { | ||||
|     WebPCleanupTransparentArea(pic); | ||||
|   } | ||||
|  | ||||
|  End: | ||||
|   return ok; | ||||
| } | ||||
| #else  // !WEBP_HAVE_PNG | ||||
| int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha) { | ||||
|   (void)in_file; | ||||
|   (void)pic; | ||||
|   (void)keep_alpha; | ||||
|   fprintf(stderr, "PNG support not compiled. Please install the libpng " | ||||
|           "development package before building.\n"); | ||||
|   return 0; | ||||
| } | ||||
| #endif  // WEBP_HAVE_PNG | ||||
|  | ||||
| // ----------------------------------------------------------------------------- | ||||
							
								
								
									
										31
									
								
								examples/pngdec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								examples/pngdec.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // Copyright 2012 Google Inc. All Rights Reserved. | ||||
| // | ||||
| // This code is licensed under the same terms as WebM: | ||||
| //  Software License Agreement:  http://www.webmproject.org/license/software/ | ||||
| //  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/ | ||||
| // ----------------------------------------------------------------------------- | ||||
| // | ||||
| // PNG decode. | ||||
|  | ||||
| #ifndef WEBP_EXAMPLES_PNGDEC_H_ | ||||
| #define WEBP_EXAMPLES_PNGDEC_H_ | ||||
|  | ||||
| #include <stdio.h> | ||||
|  | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| struct WebPPicture; | ||||
|  | ||||
| // Reads a PNG from 'in_file', returning the decoded output in 'pic'. | ||||
| // If 'keep_alpha' is true and the PNG has an alpha channel, the output is RGBA | ||||
| // otherwise it will be RGB. | ||||
| // Returns true on success. | ||||
| int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha); | ||||
|  | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| }    // extern "C" | ||||
| #endif | ||||
|  | ||||
| #endif  // WEBP_EXAMPLES_PNGDEC_H_ | ||||
| @@ -124,6 +124,9 @@ ENC_OBJS = \ | ||||
|     src/enc/vp8l.o \ | ||||
|     src/enc/webpenc.o \ | ||||
|  | ||||
| EX_FORMAT_DEC_OBJS = \ | ||||
|     examples/pngdec.o \ | ||||
|  | ||||
| EX_UTIL_OBJS = \ | ||||
|     examples/example_util.o \ | ||||
|  | ||||
| @@ -189,6 +192,8 @@ endif | ||||
|  | ||||
| all: ex | ||||
|  | ||||
| $(EX_FORMAT_DEC_OBJS): %.o: %.h | ||||
|  | ||||
| %.o: %.c $(HDRS) | ||||
| 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ | ||||
|  | ||||
| @@ -202,7 +207,7 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS) | ||||
|  | ||||
| ex: $(OUT_EXAMPLES) | ||||
|  | ||||
| examples/cwebp: examples/cwebp.o | ||||
| examples/cwebp: examples/cwebp.o $(EX_FORMAT_DEC_OBJS) | ||||
| examples/dwebp: examples/dwebp.o | ||||
| examples/gif2webp: examples/gif2webp.o | ||||
| examples/vwebp: examples/vwebp.o | ||||
|   | ||||
		Reference in New Issue
	
	Block a user