mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-19 20:08:28 +01:00
cwebp: extract png decoding to its own module
Change-Id: I80dd09fe1f1c6317e9d0cdd422438bda11b43ed5
This commit is contained in:
parent
4679db006c
commit
2ee228f9a5
@ -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)
|
||||
|
@ -20,7 +20,8 @@ dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
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 = 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
|
||||
|
Loading…
Reference in New Issue
Block a user