cwebp: add webpdec

simple webp decoding, no metadata support

Change-Id: I2752fd1442c87513922878cbf72f001d45b631bc
This commit is contained in:
James Zern 2014-04-22 19:30:27 -07:00 committed by Pascal Massimino
parent 4a0e73904d
commit ddeb6ac802
7 changed files with 123 additions and 12 deletions

View File

@ -194,6 +194,7 @@ EX_FORMAT_DEC_OBJS = \
$(DIROBJ)\examples\metadata.obj \
$(DIROBJ)\examples\pngdec.obj \
$(DIROBJ)\examples\tiffdec.obj \
$(DIROBJ)\examples\webpdec.obj \
$(DIROBJ)\examples\wicdec.obj \
EX_UTIL_OBJS = \

View File

@ -25,10 +25,12 @@ cwebp_SOURCES = cwebp.c metadata.c metadata.h stopwatch.h
cwebp_SOURCES += jpegdec.c jpegdec.h
cwebp_SOURCES += pngdec.c pngdec.h
cwebp_SOURCES += tiffdec.c tiffdec.h
cwebp_SOURCES += webpdec.c webpdec.h
cwebp_SOURCES += wicdec.c wicdec.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)
cwebp_LDADD = libexampleutil.la ../src/libwebp.la
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
gif2webp_SOURCES = gif2webp.c gif2webp_util.c
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)

View File

@ -28,6 +28,7 @@
#include "./jpegdec.h"
#include "./pngdec.h"
#include "./tiffdec.h"
#include "./webpdec.h"
#include "./wicdec.h"
#ifndef WEBP_DLL
@ -106,26 +107,30 @@ typedef enum {
PNG_ = 0,
JPEG_,
TIFF_, // 'TIFF' clashes with libtiff
WEBP_,
UNSUPPORTED
} InputFileFormat;
static InputFileFormat GetImageType(FILE* in_file) {
InputFileFormat format = UNSUPPORTED;
uint32_t magic;
uint8_t buf[4];
uint32_t magic1, magic2;
uint8_t buf[12];
if ((fread(&buf[0], 4, 1, in_file) != 1) ||
if ((fread(&buf[0], 12, 1, in_file) != 1) ||
(fseek(in_file, 0, SEEK_SET) != 0)) {
return format;
}
magic = ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
if (magic == 0x89504E47U) {
magic1 = ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
magic2 = ((uint32_t)buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
if (magic1 == 0x89504E47U) {
format = PNG_;
} else if (magic >= 0xFFD8FF00U && magic <= 0xFFD8FFFFU) {
} else if (magic1 >= 0xFFD8FF00U && magic1 <= 0xFFD8FFFFU) {
format = JPEG_;
} else if (magic == 0x49492A00 || magic == 0x4D4D002A) {
} else if (magic1 == 0x49492A00 || magic1 == 0x4D4D002A) {
format = TIFF_;
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
format = WEBP_;
}
return format;
}
@ -148,6 +153,8 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
ok = ReadJPEG(in_file, pic, metadata);
} else if (format == TIFF_) {
ok = ReadTIFF(filename, pic, keep_alpha, metadata);
} else if (format == WEBP_) {
ok = ReadWebP(filename, pic, keep_alpha, metadata);
}
} else {
// If image size is specified, infer it as YUV format.
@ -553,7 +560,7 @@ static void HelpLong(void) {
printf("Usage:\n");
printf(" cwebp [-preset <...>] [options] in_file [-o out_file]\n\n");
printf("If input size (-s) for an image is not specified, "
"it is assumed to be a PNG, JPEG or TIFF file.\n");
"it is assumed to be a PNG, JPEG, TIFF or WebP file.\n");
#ifdef HAVE_WINCODEC_H
printf("Windows builds can take as input any of the files handled by WIC\n");
#endif

67
examples/webpdec.c Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// WebP decode.
#include "./webpdec.h"
#include <stdio.h>
#include <stdlib.h>
#include "webp/decode.h"
#include "webp/encode.h"
#include "./example_util.h"
#include "./metadata.h"
int ReadWebP(const char* const in_file, WebPPicture* const pic,
int keep_alpha, Metadata* const metadata) {
int ok = 0;
size_t data_size = 0;
const uint8_t* data = NULL;
VP8StatusCode status = VP8_STATUS_OK;
WebPDecoderConfig config;
WebPDecBuffer* const output_buffer = &config.output;
WebPBitstreamFeatures* const bitstream = &config.input;
// TODO(jzern): add Exif/XMP/ICC extraction.
if (metadata != NULL) {
fprintf(stderr, "Warning: metadata extraction from WebP is unsupported.\n");
}
if (!WebPInitDecoderConfig(&config)) {
fprintf(stderr, "Library version mismatch!\n");
return 0;
}
if (ExUtilLoadWebP(in_file, &data, &data_size, bitstream)) {
const int has_alpha = keep_alpha && bitstream->has_alpha;
output_buffer->colorspace = has_alpha ? MODE_RGBA : MODE_RGB;
status = ExUtilDecodeWebP(data, data_size, 0, 0, &config);
if (status == VP8_STATUS_OK) {
const uint8_t* const rgba = output_buffer->u.RGBA.rgba;
const int stride = output_buffer->u.RGBA.stride;
pic->width = output_buffer->width;
pic->height = output_buffer->height;
pic->use_argb = 1;
ok = has_alpha ? WebPPictureImportRGBA(pic, rgba, stride)
: WebPPictureImportRGB(pic, rgba, stride);
}
}
if (status != VP8_STATUS_OK) {
ExUtilPrintWebPError(in_file, status);
}
free((void*)data);
WebPFreeDecBuffer(output_buffer);
return ok;
}
// -----------------------------------------------------------------------------

33
examples/webpdec.h Normal file
View File

@ -0,0 +1,33 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// WebP decode.
#ifndef WEBP_EXAMPLES_WEBPDEC_H_
#define WEBP_EXAMPLES_WEBPDEC_H_
#ifdef __cplusplus
extern "C" {
#endif
struct Metadata;
struct WebPPicture;
// Reads a WebP from 'in_file', returning the decoded output in 'pic'.
// If 'keep_alpha' is true and the WebP has an alpha channel, the output is
// RGBA otherwise it will be RGB.
// Returns true on success.
int ReadWebP(const char* const in_file, struct WebPPicture* const pic,
int keep_alpha, struct Metadata* const metadata);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_EXAMPLES_WEBPDEC_H_

View File

@ -148,6 +148,7 @@ EX_FORMAT_DEC_OBJS = \
examples/metadata.o \
examples/pngdec.o \
examples/tiffdec.o \
examples/webpdec.o \
EX_UTIL_OBJS = \
examples/example_util.o \
@ -252,7 +253,7 @@ examples/gif2webp: examples/gif2webp.o
examples/vwebp: examples/vwebp.o
examples/webpmux: examples/webpmux.o
examples/cwebp: src/libwebp.a
examples/cwebp: examples/libexample_util.a src/libwebp.a
examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
examples/dwebp: examples/libexample_util.a src/libwebpdecoder.a
examples/dwebp: EXTRA_LIBS += $(DWEBP_LIBS)

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH CWEBP 1 "March 11, 2014"
.TH CWEBP 1 "April 19, 2014"
.SH NAME
cwebp \- compress an image file to a WebP file
.SH SYNOPSIS
@ -12,7 +12,7 @@ This manual page documents the
command.
.PP
\fBcwebp\fP compresses an image using the WebP format.
Input format can be either PNG, JPEG, TIFF or raw Y'CbCr samples.
Input format can be either PNG, JPEG, TIFF, WebP or raw Y'CbCr samples.
.SH OPTIONS
The basic options are:
.TP