clean up jpeg image handling ready for refactor

svn path=/trunk/netsurf/; revision=12311
This commit is contained in:
Vincent Sanders 2011-05-08 15:14:21 +00:00
parent f277c59c9a
commit 658cd31311
2 changed files with 159 additions and 178 deletions

View File

@ -57,7 +57,7 @@
static char nsjpeg_error_buffer[JMSG_LENGTH_MAX];
typedef struct nsjpeg_content {
struct content base;
struct content base; /**< base content */
} nsjpeg_content;
struct nsjpeg_error_mgr {
@ -65,47 +65,6 @@ struct nsjpeg_error_mgr {
jmp_buf setjmp_buffer;
};
static nserror nsjpeg_create(const content_handler *handler,
lwc_string *imime_type, const http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static bool nsjpeg_convert(struct content *c);
static void nsjpeg_destroy(struct content *c);
static bool nsjpeg_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour);
static bool nsjpeg_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour,
bool repeat_x, bool repeat_y);
static nserror nsjpeg_clone(const struct content *old, struct content **newc);
static content_type nsjpeg_content_type(lwc_string *mime_type);
static void nsjpeg_error_exit(j_common_ptr cinfo);
static void nsjpeg_init_source(j_decompress_ptr cinfo);
static boolean nsjpeg_fill_input_buffer(j_decompress_ptr cinfo);
static void nsjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes);
static void nsjpeg_term_source(j_decompress_ptr cinfo);
static const content_handler nsjpeg_content_handler = {
nsjpeg_create,
NULL,
nsjpeg_convert,
NULL,
nsjpeg_destroy,
NULL,
NULL,
NULL,
nsjpeg_redraw,
nsjpeg_redraw_tiled,
NULL,
NULL,
nsjpeg_clone,
NULL,
nsjpeg_content_type,
false
};
static const char *nsjpeg_types[] = {
"image/jpeg",
"image/jpg",
@ -114,46 +73,12 @@ static const char *nsjpeg_types[] = {
static lwc_string *nsjpeg_mime_types[NOF_ELEMENTS(nsjpeg_types)];
nserror nsjpeg_init(void)
{
uint32_t i;
lwc_error lerror;
nserror error;
static unsigned char nsjpeg_eoi[] = { 0xff, JPEG_EOI };
for (i = 0; i < NOF_ELEMENTS(nsjpeg_mime_types); i++) {
lerror = lwc_intern_string(nsjpeg_types[i],
strlen(nsjpeg_types[i]),
&nsjpeg_mime_types[i]);
if (lerror != lwc_error_ok) {
error = NSERROR_NOMEM;
goto error;
}
error = content_factory_register_handler(nsjpeg_mime_types[i],
&nsjpeg_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK;
error:
nsjpeg_fini();
return error;
}
void nsjpeg_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsjpeg_mime_types); i++) {
if (nsjpeg_mime_types[i] != NULL)
lwc_string_unref(nsjpeg_mime_types[i]);
}
}
nserror nsjpeg_create(const content_handler *handler,
/**
* Content create entry point.
*/
static nserror nsjpeg_create(const content_handler *handler,
lwc_string *imime_type, const http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c)
@ -166,7 +91,7 @@ nserror nsjpeg_create(const content_handler *handler,
return NSERROR_NOMEM;
error = content__init(&jpeg->base, handler, imime_type, params,
llcache, fallback_charset, quirks);
llcache, fallback_charset, quirks);
if (error != NSERROR_OK) {
talloc_free(jpeg);
return error;
@ -178,17 +103,75 @@ nserror nsjpeg_create(const content_handler *handler,
}
/**
* Convert a CONTENT_JPEG for display.
* JPEG data source manager: initialize source.
*/
static void nsjpeg_init_source(j_decompress_ptr cinfo)
{
}
/**
* JPEG data source manager: fill the input buffer.
*
* This can only occur if the JPEG data was truncated or corrupted. Insert a
* fake EOI marker to allow the decompressor to output as much as possible.
*/
static boolean nsjpeg_fill_input_buffer(j_decompress_ptr cinfo)
{
cinfo->src->next_input_byte = nsjpeg_eoi;
cinfo->src->bytes_in_buffer = 2;
return TRUE;
}
/**
* JPEG data source manager: skip num_bytes worth of data.
*/
bool nsjpeg_convert(struct content *c)
static void nsjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
if ((long) cinfo->src->bytes_in_buffer < num_bytes) {
cinfo->src->next_input_byte = 0;
cinfo->src->bytes_in_buffer = 0;
} else {
cinfo->src->next_input_byte += num_bytes;
cinfo->src->bytes_in_buffer -= num_bytes;
}
}
/**
* JPEG data source manager: terminate source.
*/
static void nsjpeg_term_source(j_decompress_ptr cinfo)
{
}
/**
* Fatal error handler for JPEG library.
*
* This prevents jpeglib calling exit() on a fatal error.
*/
static void nsjpeg_error_exit(j_common_ptr cinfo)
{
struct nsjpeg_error_mgr *err = (struct nsjpeg_error_mgr *) cinfo->err;
err->pub.format_message(cinfo, nsjpeg_error_buffer);
longjmp(err->setjmp_buffer, 1);
}
/**
* Convert a CONTENT_JPEG for display.
*/
static bool nsjpeg_convert(struct content *c)
{
struct jpeg_decompress_struct cinfo;
struct nsjpeg_error_mgr jerr;
struct jpeg_source_mgr source_mgr = { 0, 0,
nsjpeg_init_source, nsjpeg_fill_input_buffer,
nsjpeg_skip_input_data, jpeg_resync_to_restart,
nsjpeg_term_source };
nsjpeg_init_source, nsjpeg_fill_input_buffer,
nsjpeg_skip_input_data, jpeg_resync_to_restart,
nsjpeg_term_source };
unsigned int height;
unsigned int width;
struct bitmap * volatile bitmap = NULL;
@ -245,7 +228,7 @@ bool nsjpeg_convert(struct content *c)
JSAMPROW scanlines[1];
scanlines[0] = (JSAMPROW) (pixels +
rowstride * cinfo.output_scanline);
rowstride * cinfo.output_scanline);
jpeg_read_scanlines(&cinfo, scanlines, 1);
#if RGB_RED != 0 || RGB_GREEN != 1 || RGB_BLUE != 2 || RGB_PIXELSIZE != 4
@ -270,7 +253,7 @@ bool nsjpeg_convert(struct content *c)
c->height = height;
c->bitmap = bitmap;
snprintf(title, sizeof(title), messages_get("JPEGTitle"),
width, height, size);
width, height, size);
content__set_title(c, title);
c->size += height * rowstride;
content_set_ready(c);
@ -282,88 +265,31 @@ bool nsjpeg_convert(struct content *c)
/**
* Fatal error handler for JPEG library.
*
* This prevents jpeglib calling exit() on a fatal error.
* Destroy a CONTENT_JPEG and free all resources it owns.
*/
void nsjpeg_error_exit(j_common_ptr cinfo)
{
struct nsjpeg_error_mgr *err = (struct nsjpeg_error_mgr *) cinfo->err;
err->pub.format_message(cinfo, nsjpeg_error_buffer);
longjmp(err->setjmp_buffer, 1);
}
/**
* JPEG data source manager: initialize source.
*/
void nsjpeg_init_source(j_decompress_ptr cinfo)
{
}
static unsigned char nsjpeg_eoi[] = { 0xff, JPEG_EOI };
/**
* JPEG data source manager: fill the input buffer.
*
* This can only occur if the JPEG data was truncated or corrupted. Insert a
* fake EOI marker to allow the decompressor to output as much as possible.
*/
boolean nsjpeg_fill_input_buffer(j_decompress_ptr cinfo)
{
cinfo->src->next_input_byte = nsjpeg_eoi;
cinfo->src->bytes_in_buffer = 2;
return TRUE;
}
/**
* JPEG data source manager: skip num_bytes worth of data.
*/
void nsjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
if ((long) cinfo->src->bytes_in_buffer < num_bytes) {
cinfo->src->next_input_byte = 0;
cinfo->src->bytes_in_buffer = 0;
} else {
cinfo->src->next_input_byte += num_bytes;
cinfo->src->bytes_in_buffer -= num_bytes;
}
}
/**
* JPEG data source manager: terminate source.
*/
void nsjpeg_term_source(j_decompress_ptr cinfo)
static void nsjpeg_destroy(struct content *c)
{
if (c->bitmap)
bitmap_destroy(c->bitmap);
}
/**
* Redraw a CONTENT_JPEG.
*/
bool nsjpeg_redraw(struct content *c, int x, int y,
static bool nsjpeg_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
return plot.bitmap(x, y, width, height,
c->bitmap, background_colour, BITMAPF_NONE);
c->bitmap, background_colour, BITMAPF_NONE);
}
/**
* Redraw a CONTENT_JPEG with appropriate tiling.
*/
bool nsjpeg_redraw_tiled(struct content *c, int x, int y,
static bool nsjpeg_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour,
bool repeat_x, bool repeat_y)
@ -376,54 +302,107 @@ bool nsjpeg_redraw_tiled(struct content *c, int x, int y,
flags |= BITMAPF_REPEAT_Y;
return plot.bitmap(x, y, width, height,
c->bitmap, background_colour,
flags);
c->bitmap, background_colour,
flags);
}
/**
* Destroy a CONTENT_JPEG and free all resources it owns.
* Clone content.
*/
void nsjpeg_destroy(struct content *c)
static nserror nsjpeg_clone(const struct content *old, struct content **newc)
{
if (c->bitmap)
bitmap_destroy(c->bitmap);
}
nserror nsjpeg_clone(const struct content *old, struct content **newc)
{
nsjpeg_content *jpeg;
nsjpeg_content *jpeg_c;
nserror error;
jpeg = talloc_zero(0, nsjpeg_content);
if (jpeg == NULL)
jpeg_c = talloc_zero(0, nsjpeg_content);
if (jpeg_c == NULL)
return NSERROR_NOMEM;
error = content__clone(old, &jpeg->base);
error = content__clone(old, &jpeg_c->base);
if (error != NSERROR_OK) {
content_destroy(&jpeg->base);
content_destroy(&jpeg_c->base);
return error;
}
/* Simply replay conversion */
if (old->status == CONTENT_STATUS_READY ||
old->status == CONTENT_STATUS_DONE) {
if (nsjpeg_convert(&jpeg->base) == false) {
content_destroy(&jpeg->base);
/* re-convert if the content is ready */
if ((old->status == CONTENT_STATUS_READY) ||
(old->status == CONTENT_STATUS_DONE)) {
if (nsjpeg_convert(&jpeg_c->base) == false) {
content_destroy(&jpeg_c->base);
return NSERROR_CLONE_FAILED;
}
}
*newc = (struct content *) jpeg;
*newc = (struct content *)jpeg_c;
return NSERROR_OK;
}
content_type nsjpeg_content_type(lwc_string *mime_type)
static content_type nsjpeg_content_type(lwc_string *mime_type)
{
return CONTENT_IMAGE;
}
static const content_handler nsjpeg_content_handler = {
nsjpeg_create,
NULL,
nsjpeg_convert,
NULL,
nsjpeg_destroy,
NULL,
NULL,
NULL,
nsjpeg_redraw,
nsjpeg_redraw_tiled,
NULL,
NULL,
nsjpeg_clone,
NULL,
nsjpeg_content_type,
false
};
nserror nsjpeg_init(void)
{
uint32_t i;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(nsjpeg_mime_types); i++) {
lerror = lwc_intern_string(nsjpeg_types[i],
strlen(nsjpeg_types[i]),
&nsjpeg_mime_types[i]);
if (lerror != lwc_error_ok) {
error = NSERROR_NOMEM;
goto error;
}
error = content_factory_register_handler(nsjpeg_mime_types[i],
&nsjpeg_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK;
error:
nsjpeg_fini();
return error;
}
void nsjpeg_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsjpeg_mime_types); i++) {
if (nsjpeg_mime_types[i] != NULL) {
lwc_string_unref(nsjpeg_mime_types[i]);
}
}
}
#endif /* WITH_JPEG */

View File

@ -53,7 +53,7 @@
#endif
typedef struct nspng_content {
struct content base;
struct content base; /**< base content type */
png_structp png;
png_infop info;
@ -323,6 +323,8 @@ static bool nspng_convert(struct content *c)
bitmap_set_opaque(png_c->bitmap, bitmap_test_opaque(png_c->bitmap));
bitmap_modified(png_c->bitmap);
c->bitmap = png_c->bitmap; /* this needs to go */
content_set_ready(c);
content_set_done(c);
content_set_status(c, "");