mirror of
https://github.com/webmproject/libwebp.git
synced 2025-01-26 14:42:55 +01:00
make ReadPNG and ReadJPEG take a filename instead of a FILE
-> read is a bit slower (memory allocation and such) than reading directly from disk. -> we're not yet ready to accept stdin as input (-- -) because we still need to guess the file type with GetImageType(). And since we can't rewind on stdin, this will need a bit more work before being able to read from stdin. Change-Id: I6491fac4b07d28d1854518325ead88669656ddbf
This commit is contained in:
parent
d478e58960
commit
4c60f63c64
@ -155,9 +155,9 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||
}
|
||||
format = GetImageType(in_file);
|
||||
if (format == PNG_) {
|
||||
ok = ReadPNG(in_file, pic, keep_alpha, metadata);
|
||||
ok = ReadPNG(filename, pic, keep_alpha, metadata);
|
||||
} else if (format == JPEG_) {
|
||||
ok = ReadJPEG(in_file, pic, metadata);
|
||||
ok = ReadJPEG(filename, pic, metadata);
|
||||
} else if (format == TIFF_) {
|
||||
ok = ReadTIFF(filename, pic, keep_alpha, metadata);
|
||||
} else if (format == WEBP_) {
|
||||
|
@ -19,11 +19,13 @@
|
||||
|
||||
#ifdef WEBP_HAVE_JPEG
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webp/encode.h"
|
||||
#include "./example_util.h"
|
||||
#include "./metadata.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -208,13 +210,64 @@ static void my_error_exit(j_common_ptr dinfo) {
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
int ReadJPEG(FILE* in_file, WebPPicture* const pic, Metadata* const metadata) {
|
||||
int ok = 0;
|
||||
typedef struct {
|
||||
struct jpeg_source_mgr pub;
|
||||
const uint8_t* data;
|
||||
size_t data_size;
|
||||
} JPEGReadContext;
|
||||
|
||||
static void ContextInit(j_decompress_ptr cinfo) {
|
||||
JPEGReadContext* const ctx = (JPEGReadContext*)cinfo->src;
|
||||
ctx->pub.next_input_byte = ctx->data;
|
||||
ctx->pub.bytes_in_buffer = ctx->data_size;
|
||||
}
|
||||
|
||||
static int ContextFill(j_decompress_ptr cinfo) {
|
||||
// we shouldn't get here.
|
||||
ERREXIT(cinfo, JERR_FILE_READ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ContextSkip(j_decompress_ptr cinfo, long jump_size) {
|
||||
JPEGReadContext* const ctx = (JPEGReadContext*)cinfo->src;
|
||||
size_t jump = (size_t)jump_size;
|
||||
if (jump > ctx->pub.bytes_in_buffer) { // Don't overflow the buffer.
|
||||
jump = ctx->pub.bytes_in_buffer;
|
||||
}
|
||||
ctx->pub.bytes_in_buffer -= jump;
|
||||
ctx->pub.next_input_byte += jump;
|
||||
}
|
||||
|
||||
static void ContextTerm(j_decompress_ptr cinfo) {
|
||||
(void)cinfo;
|
||||
}
|
||||
|
||||
static void ContextSetup(volatile struct jpeg_decompress_struct* const cinfo,
|
||||
JPEGReadContext* const ctx) {
|
||||
cinfo->src = (struct jpeg_source_mgr*)ctx;
|
||||
ctx->pub.init_source = ContextInit;
|
||||
ctx->pub.fill_input_buffer = ContextFill;
|
||||
ctx->pub.skip_input_data = ContextSkip;
|
||||
ctx->pub.resync_to_restart = jpeg_resync_to_restart;
|
||||
ctx->pub.term_source = ContextTerm;
|
||||
ctx->pub.bytes_in_buffer = 0;
|
||||
ctx->pub.next_input_byte = NULL;
|
||||
}
|
||||
|
||||
int ReadJPEG(const char* const filename, WebPPicture* const pic,
|
||||
Metadata* const metadata) {
|
||||
volatile int ok = 0;
|
||||
int stride, width, height;
|
||||
volatile struct jpeg_decompress_struct dinfo;
|
||||
struct my_error_mgr jerr;
|
||||
uint8_t* volatile rgb = NULL;
|
||||
JSAMPROW buffer[1];
|
||||
JPEGReadContext ctx;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
||||
ok = ExUtilReadFile(filename, &ctx.data, &ctx.data_size);
|
||||
if (!ok) goto End;
|
||||
|
||||
memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo)); // for setjmp sanity
|
||||
dinfo.err = jpeg_std_error(&jerr.pub);
|
||||
@ -228,7 +281,7 @@ int ReadJPEG(FILE* in_file, WebPPicture* const pic, Metadata* const metadata) {
|
||||
}
|
||||
|
||||
jpeg_create_decompress((j_decompress_ptr)&dinfo);
|
||||
jpeg_stdio_src((j_decompress_ptr)&dinfo, in_file);
|
||||
ContextSetup(&dinfo, &ctx);
|
||||
if (metadata != NULL) SaveMetadataMarkers((j_decompress_ptr)&dinfo);
|
||||
jpeg_read_header((j_decompress_ptr)&dinfo, TRUE);
|
||||
|
||||
@ -277,12 +330,14 @@ int ReadJPEG(FILE* in_file, WebPPicture* const pic, Metadata* const metadata) {
|
||||
|
||||
End:
|
||||
free(rgb);
|
||||
free((void*)ctx.data);
|
||||
return ok;
|
||||
}
|
||||
#else // !WEBP_HAVE_JPEG
|
||||
int ReadJPEG(FILE* in_file, struct WebPPicture* const pic,
|
||||
int ReadJPEG(const char* const filename,
|
||||
struct WebPPicture* const pic,
|
||||
struct Metadata* const metadata) {
|
||||
(void)in_file;
|
||||
(void)filename;
|
||||
(void)pic;
|
||||
(void)metadata;
|
||||
fprintf(stderr, "JPEG support not compiled. Please install the libjpeg "
|
||||
|
@ -22,10 +22,11 @@ extern "C" {
|
||||
struct Metadata;
|
||||
struct WebPPicture;
|
||||
|
||||
// Reads a JPEG from 'in_file', returning the decoded output in 'pic'.
|
||||
// Reads a JPEG from 'filename', returning the decoded output in 'pic'.
|
||||
// If 'filename' is equal '-', input is read from stdin.
|
||||
// The output is RGB or YUV depending on pic->use_argb value.
|
||||
// Returns true on success.
|
||||
int ReadJPEG(FILE* in_file, struct WebPPicture* const pic,
|
||||
int ReadJPEG(const char* const filename, struct WebPPicture* const pic,
|
||||
struct Metadata* const metadata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -18,12 +18,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WEBP_HAVE_PNG
|
||||
#include <assert.h>
|
||||
#include <png.h>
|
||||
#include <setjmp.h> // note: this must be included *after* png.h
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webp/encode.h"
|
||||
#include "./example_util.h"
|
||||
#include "./metadata.h"
|
||||
|
||||
static void PNGAPI error_function(png_structp png, png_const_charp error) {
|
||||
@ -188,24 +190,39 @@ static int ExtractMetadataFromPNG(png_structp png,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha,
|
||||
Metadata* const metadata) {
|
||||
volatile png_structp png;
|
||||
typedef struct {
|
||||
const uint8_t* data;
|
||||
size_t data_size;
|
||||
png_size_t offset;
|
||||
} PNGReadContext;
|
||||
|
||||
static void ReadFunc(png_structp png_ptr, png_bytep data, png_size_t length) {
|
||||
PNGReadContext* const ctx = (PNGReadContext*)png_get_io_ptr(png_ptr);
|
||||
assert(ctx->offset + length <= ctx->data_size);
|
||||
memcpy(data, ctx->data + ctx->offset, length);
|
||||
ctx->offset += length;
|
||||
}
|
||||
|
||||
int ReadPNG(const char* const filename, struct WebPPicture* const pic,
|
||||
int keep_alpha, struct Metadata* const metadata) {
|
||||
volatile png_structp png = NULL;
|
||||
volatile png_infop info = NULL;
|
||||
volatile png_infop end_info = NULL;
|
||||
PNGReadContext context = { NULL, 0, 0 };
|
||||
int color_type, bit_depth, interlaced;
|
||||
int has_alpha;
|
||||
int num_passes;
|
||||
int p;
|
||||
int ok = 0;
|
||||
volatile int ok = 0;
|
||||
png_uint_32 width, height, y;
|
||||
png_uint_32 stride;
|
||||
uint8_t* volatile rgb = NULL;
|
||||
|
||||
ok = ExUtilReadFile(filename, &context.data, &context.data_size);
|
||||
if (!ok) goto End;
|
||||
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
|
||||
if (png == NULL) {
|
||||
goto End;
|
||||
}
|
||||
if (png == NULL) goto End;
|
||||
|
||||
png_set_error_fn(png, 0, error_function, NULL);
|
||||
if (setjmp(png_jmpbuf(png))) {
|
||||
@ -219,7 +236,7 @@ int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha,
|
||||
end_info = png_create_info_struct(png);
|
||||
if (end_info == NULL) goto Error;
|
||||
|
||||
png_init_io(png, in_file);
|
||||
png_set_read_fn(png, &context, ReadFunc);
|
||||
png_read_info(png, info);
|
||||
if (!png_get_IHDR(png, info,
|
||||
&width, &height, &bit_depth, &color_type, &interlaced,
|
||||
@ -282,13 +299,14 @@ int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha,
|
||||
png_destroy_read_struct((png_structpp)&png,
|
||||
(png_infopp)&info, (png_infopp)&end_info);
|
||||
}
|
||||
free((void*)context.data);
|
||||
free(rgb);
|
||||
return ok;
|
||||
}
|
||||
#else // !WEBP_HAVE_PNG
|
||||
int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha,
|
||||
struct Metadata* const metadata) {
|
||||
(void)in_file;
|
||||
int ReadPNG(const char* const filename, struct WebPPicture* const pic,
|
||||
int keep_alpha, struct Metadata* const metadata) {
|
||||
(void)filename;
|
||||
(void)pic;
|
||||
(void)keep_alpha;
|
||||
(void)metadata;
|
||||
|
@ -21,13 +21,14 @@ extern "C" {
|
||||
struct Metadata;
|
||||
struct WebPPicture;
|
||||
|
||||
// Reads a PNG from 'in_file', returning the decoded output in 'pic'.
|
||||
// Reads a PNG from 'filename', returning the decoded output in 'pic'.
|
||||
// If 'filename' is equal '-', input is read from stdin.
|
||||
// Output is RGBA or YUVA, depending on pic->use_argb value.
|
||||
// If 'keep_alpha' is true and the PNG has an alpha channel, the output is RGBA
|
||||
// or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV.
|
||||
// Returns true on success.
|
||||
int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha,
|
||||
struct Metadata* const metadata);
|
||||
int ReadPNG(const char* const filename, struct WebPPicture* const pic,
|
||||
int keep_alpha, struct Metadata* const metadata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
Loading…
x
Reference in New Issue
Block a user