diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/dicache.c | 48 | ||||
-rw-r--r-- | src/dicache.h | 8 | ||||
-rw-r--r-- | src/gif.c | 14 | ||||
-rw-r--r-- | src/image.cc | 100 | ||||
-rw-r--r-- | src/image.hh | 4 | ||||
-rw-r--r-- | src/jpeg.c | 18 | ||||
-rw-r--r-- | src/png.c | 17 |
8 files changed, 80 insertions, 131 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e87c8d74..e944fb98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -89,6 +89,8 @@ dillo_SOURCES = \ gif.c \ jpeg.c \ png.c \ + imgbuf.cc \ + imgbuf.hh \ image.cc \ image.hh \ menu.hh \ diff --git a/src/dicache.c b/src/dicache.c index fb1a0c8c..1585ee1f 100644 --- a/src/dicache.c +++ b/src/dicache.c @@ -14,7 +14,9 @@ #include <stdio.h> #include <stdlib.h> +#include "msg.h" #include "image.hh" +#include "imgbuf.hh" #include "web.hh" #include "dicache.h" #include "cache.h" @@ -88,6 +90,10 @@ static DICacheEntry *Dicache_entry_new(void) entry->State = DIC_Empty; entry->version = 0; + entry->Decoder = NULL; + entry->DecoderData = NULL; + entry->DecodedSize = 0; + entry->next = NULL; return entry; @@ -187,7 +193,7 @@ static void Dicache_remove(const DilloUrl *Url, int version) dFree(entry->cmap); dFree(entry->linebuf); a_Bitvec_free(entry->BitVec); - a_Image_imgbuf_unref(entry->v_imgbuf); + a_Imgbuf_unref(entry->v_imgbuf); dicache_size_total -= entry->TotalSize; if (node->first == entry) { @@ -214,7 +220,6 @@ void a_Dicache_unref(const DilloUrl *Url, int version) DICacheEntry *entry; if ((entry = Dicache_get_entry_version(Url, version))) { - /*if (--entry->RefCount == 0 && (entry->next || !prefs.use_dicache)) {*/ if (--entry->RefCount == 0) { Dicache_remove(Url, version); } @@ -262,6 +267,12 @@ void a_Dicache_callback(int Op, CacheClient_t *Client) dReturn_if_fail ( DicEntry != NULL ); + /* Only call the decoder when necessary */ + if (DicEntry->State < DIC_Close && + DicEntry->DecodedSize < Client->BufSize) { + DicEntry->Decoder(Op, Client); + } + /* when the data stream is not an image 'v_imgbuf' remains NULL */ if (Op == CA_Send && DicEntry->v_imgbuf) { if (Image->height == 0 && DicEntry->State >= DIC_SetParms) { @@ -309,6 +320,7 @@ void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, { DICacheEntry *DicEntry; + MSG("a_Dicache_set_parms\n"); dReturn_if_fail ( Image != NULL && width && height ); /* Find the DicEntry for this Image */ DicEntry = Dicache_get_entry_version(url, version); @@ -322,11 +334,11 @@ void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, /* BUG: there's just one image-type now */ #define I_RGB 0 - DicEntry->v_imgbuf = a_Image_imgbuf_new(Image->dw, I_RGB, width, height); + DicEntry->v_imgbuf = a_Imgbuf_new(Image->dw, I_RGB, width, height); /* This extra reference activates the dicache ALWAYS. * Extra code is necessary in Imgbuf to be able to free it */ - //a_Image_imgbuf_ref(DicEntry->v_imgbuf); + //a_Imgbuf_ref(DicEntry->v_imgbuf); DicEntry->TotalSize = width * height * 3; DicEntry->width = width; @@ -337,9 +349,11 @@ void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, dicache_size_total += DicEntry->TotalSize; +#if 0 /* Allocate and initialize this image */ a_Image_set_parms(Image, DicEntry->v_imgbuf, url, version, width, height, type); +#endif } /* @@ -362,24 +376,28 @@ void a_Dicache_set_cmap(DilloUrl *url, int version, DilloImage *Image, DicEntry->cmap[bg_index * 3 + 2] = (Image->bg_color) & 0xff; } - a_Image_set_cmap(Image, DicEntry->cmap); + //a_Image_set_cmap(Image, DicEntry->cmap); DicEntry->State = DIC_SetCmap; } /* * Reset for a new scan from a multiple-scan image. */ -void a_Dicache_new_scan(DilloImage *image, const DilloUrl *url, int version) +void a_Dicache_new_scan(const DilloUrl *url, int version) { DICacheEntry *DicEntry; + MSG("a_Dicache_new_scan\n"); dReturn_if_fail ( url != NULL ); DicEntry = Dicache_get_entry_version(url, version); dReturn_if_fail ( DicEntry != NULL ); - + if (DicEntry->State < DIC_SetParms) { + MSG("a_Dicache_new_scan before DIC_SetParms\n"); + exit(-1); + } a_Bitvec_clear(DicEntry->BitVec); DicEntry->ScanNumber++; - a_Image_new_scan(image, DicEntry->v_imgbuf); + //a_Image_new_scan(image, DicEntry->v_imgbuf); } /* @@ -393,12 +411,17 @@ void a_Dicache_write(DilloImage *Image, DilloUrl *url, int version, { DICacheEntry *DicEntry; + MSG("a_Dicache_write\n"); dReturn_if_fail ( Image != NULL ); DicEntry = Dicache_get_entry_version(url, version); dReturn_if_fail ( DicEntry != NULL ); dReturn_if_fail ( DicEntry->width > 0 && DicEntry->height > 0 ); - a_Image_write(Image, DicEntry->v_imgbuf, buf, Y, TRUE); + /* update the common buffer in the imgbuf */ + a_Imgbuf_update(DicEntry->v_imgbuf, buf, DicEntry->type, + DicEntry->cmap, DicEntry->width, DicEntry->height, Y); + //a_Image_write(Image, DicEntry->v_imgbuf, buf, Y, TRUE); + DicEntry->Y = Y; a_Bitvec_set_bit(DicEntry->BitVec, (int)Y); DicEntry->State = DIC_Write; @@ -412,6 +435,7 @@ void a_Dicache_close(DilloUrl *url, int version, CacheClient_t *Client) DilloWeb *Web = Client->Web; DICacheEntry *DicEntry = Dicache_get_entry_version(url, version); + MSG("a_Dicache_close\n"); dReturn_if_fail ( DicEntry != NULL ); DicEntry->State = DIC_Close; @@ -419,7 +443,7 @@ void a_Dicache_close(DilloUrl *url, int version, CacheClient_t *Client) DicEntry->cmap = NULL; dFree(DicEntry->linebuf); DicEntry->linebuf = NULL; - a_Image_close(Web->Image); + //a_Image_close(Web->Image); a_Bw_close_client(Web->bw, Client->Key); } @@ -437,7 +461,7 @@ void a_Dicache_cleanup(void) /* iterate each entry of this node */ for (entry = node->first; entry; entry = entry->next) { if (entry->v_imgbuf && - a_Image_imgbuf_last_reference(entry->v_imgbuf)) { + a_Imgbuf_last_reference(entry->v_imgbuf)) { /* free this unused entry */ if (entry->next) { Dicache_remove(node->url, entry->version); @@ -469,7 +493,7 @@ void a_Dicache_freeall(void) dFree(entry->cmap); dFree(entry->linebuf); a_Bitvec_free(entry->BitVec); - a_Image_imgbuf_unref(entry->v_imgbuf); + a_Imgbuf_unref(entry->v_imgbuf); dicache_size_total -= entry->TotalSize; } dList_remove(CachedIMGs, node); diff --git a/src/dicache.h b/src/dicache.h index c78d0953..faec2b07 100644 --- a/src/dicache.h +++ b/src/dicache.h @@ -37,6 +37,11 @@ struct _DICacheEntry { int RefCount; /* Reference Counter */ int version; /* Version number, used for different versions of the same URL image */ + + CA_Callback_t Decoder; /* Client function */ + void *DecoderData; /* Client function data */ + uint_t DecodedSize; /* Size of already decoded data */ + DICacheEntry *next; /* Link to the next "newer" version */ }; @@ -47,13 +52,14 @@ DICacheEntry *a_Dicache_get_entry(const DilloUrl *Url); DICacheEntry *a_Dicache_add_entry(const DilloUrl *Url); void a_Dicache_callback(int Op, CacheClient_t *Client); +void a_Dicache_callback2(int Op, CacheClient_t *Client); void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, uint_t width, uint_t height, DilloImgType type); void a_Dicache_set_cmap(DilloUrl *url, int version, DilloImage *Image, const uchar_t *cmap, uint_t num_colors, int num_colors_max, int bg_index); -void a_Dicache_new_scan(DilloImage *image, const DilloUrl *url, int version); +void a_Dicache_new_scan(const DilloUrl *url, int version); void a_Dicache_write(DilloImage *Image, DilloUrl *url, int version, const uchar_t *buf, uint_t Y); void a_Dicache_close(DilloUrl *url, int version, CacheClient_t *Client); @@ -176,16 +176,16 @@ void *a_Gif_image(const char *Type, void *Ptr, CA_Callback_t *Call, if (!DicEntry) { /* Let's create an entry for this image... */ DicEntry = a_Dicache_add_entry(web->url); - - /* ... and let the decoder feed it! */ - *Data = Gif_new(web->Image, DicEntry->url, DicEntry->version); - *Call = (CA_Callback_t) Gif_callback; + DicEntry->DecoderData = + Gif_new(web->Image, DicEntry->url, DicEntry->version); } else { - /* Let's feed our client from the dicache */ + /* Repeated image */ a_Dicache_ref(DicEntry->url, DicEntry->version); - *Data = web->Image; - *Call = (CA_Callback_t) a_Dicache_callback; } + DicEntry->Decoder = Gif_callback; + *Data = DicEntry->DecoderData; + *Call = (CA_Callback_t) a_Dicache_callback; + return (web->Image->dw); } diff --git a/src/image.cc b/src/image.cc index 462ec90c..3cb12eb0 100644 --- a/src/image.cc +++ b/src/image.cc @@ -31,13 +31,6 @@ using namespace dw::core; /* - * Local data - */ -static size_t linebuf_size = 0; -static uchar_t *linebuf = NULL; - - -/* * Create and initialize a new image structure. */ DilloImage *a_Image_new(int width, @@ -92,44 +85,13 @@ void a_Image_ref(DilloImage *Image) } /* - * Decode 'buf' (an image line) into RGB format. - */ -static uchar_t * - Image_line(DilloImage *Image, const uchar_t *buf, const uchar_t *cmap, int y) -{ - uint_t x; - - switch (Image->in_type) { - case DILLO_IMG_TYPE_INDEXED: - if (cmap) { - for (x = 0; x < Image->width; x++) - memcpy(linebuf + x * 3, cmap + buf[x] * 3, 3); - } else { - MSG("Gif:: WARNING, image lacks a color map\n"); - } - break; - case DILLO_IMG_TYPE_GRAY: - for (x = 0; x < Image->width; x++) - memset(linebuf + x * 3, buf[x], 3); - break; - case DILLO_IMG_TYPE_RGB: - /* avoid a memcpy here! --Jcid */ - return (uchar_t *)buf; - case DILLO_IMG_TYPE_NOTSET: - MSG_ERR("Image_line: type not set...\n"); - break; - } - return linebuf; -} - -/* * Set initial parameters of the image */ void a_Image_set_parms(DilloImage *Image, void *v_imgbuf, DilloUrl *url, int version, uint_t width, uint_t height, DilloImgType type) { - _MSG("a_Image_set_parms: width=%d height=%d\n", width, height); + MSG("a_Image_set_parms: width=%d height=%d\n", width, height); bool resize = (Image->width != width || Image->height != height); OI(Image)->setBuffer((Imgbuf*)v_imgbuf, resize); @@ -139,10 +101,6 @@ void a_Image_set_parms(DilloImage *Image, void *v_imgbuf, DilloUrl *url, Image->in_type = type; Image->width = width; Image->height = height; - if (3 * width > linebuf_size) { - linebuf_size = 3 * width; - linebuf = (uchar_t*) dRealloc(linebuf, linebuf_size); - } Image->State = IMG_SetParms; } @@ -151,6 +109,7 @@ void a_Image_set_parms(DilloImage *Image, void *v_imgbuf, DilloUrl *url, */ void a_Image_set_cmap(DilloImage *Image, const uchar_t *cmap) { + MSG("a_Image_set_cmap\n"); Image->cmap = cmap; Image->State = IMG_SetCmap; } @@ -160,6 +119,7 @@ void a_Image_set_cmap(DilloImage *Image, const uchar_t *cmap) */ void a_Image_new_scan(DilloImage *Image, void *v_imgbuf) { + MSG("a_Image_new_scan\n"); a_Bitvec_clear(Image->BitVec); Image->ScanNumber++; ((Imgbuf*)v_imgbuf)->newScan(); @@ -171,20 +131,13 @@ void a_Image_new_scan(DilloImage *Image, void *v_imgbuf) void a_Image_write(DilloImage *Image, void *v_imgbuf, const uchar_t *buf, uint_t y, int decode) { - const uchar_t *newbuf; - + MSG("a_Image_write\n"); dReturn_if_fail ( y < Image->height ); - if (decode) { - /* Decode 'buf' and copy it into the DicEntry buffer */ - newbuf = Image_line(Image, buf, Image->cmap, y); - ((Imgbuf*)v_imgbuf)->copyRow(y, (byte *)newbuf); - } - a_Bitvec_set_bit(Image->BitVec, y); - Image->State = IMG_Write; - /* Update the row in DwImage */ OI(Image)->drawRow(y); + a_Bitvec_set_bit(Image->BitVec, y); + Image->State = IMG_Write; } /* @@ -192,46 +145,7 @@ void a_Image_write(DilloImage *Image, void *v_imgbuf, */ void a_Image_close(DilloImage *Image) { + MSG("a_Image_close\n"); a_Image_unref(Image); } - -// Wrappers for Imgbuf ------------------------------------------------------- - -/* - * Increment reference count for an Imgbuf - */ -void a_Image_imgbuf_ref(void *v_imgbuf) -{ - ((Imgbuf*)v_imgbuf)->ref(); -} - -/* - * Decrement reference count for an Imgbuf - */ -void a_Image_imgbuf_unref(void *v_imgbuf) -{ - ((Imgbuf*)v_imgbuf)->unref(); -} - -/* - * Create a new Imgbuf - */ -void *a_Image_imgbuf_new(void *v_dw, int img_type, int width, int height) -{ - Layout *layout = ((Widget*)v_dw)->getLayout(); - if (!layout) { - MSG_ERR("a_Image_imgbuf_new: layout is NULL.\n"); - exit(1); - } - return (void*)layout->createImgbuf(Imgbuf::RGB, width, height); -} - -/* - * Last reference for this Imgbuf? - */ -int a_Image_imgbuf_last_reference(void *v_imgbuf) -{ - return ((Imgbuf*)v_imgbuf)->lastReference () ? 1 : 0; -} - diff --git a/src/image.hh b/src/image.hh index ce906c74..beccfb21 100644 --- a/src/image.hh +++ b/src/image.hh @@ -69,8 +69,10 @@ void a_Image_close(DilloImage *Image); void a_Image_imgbuf_ref(void *v_imgbuf); void a_Image_imgbuf_unref(void *v_imgbuf); -void *a_Image_imgbuf_new(void *v_dw, int img_type, int width, int height) ; +void *a_Image_imgbuf_new(void *v_dw, int img_type, int width, int height); int a_Image_imgbuf_last_reference(void *v_imgbuf); +void a_Image_imgbuf_update(DilloImage *Image, void *v_imgbuf, + const uchar_t *buf, uint_t y); #ifdef __cplusplus } @@ -121,16 +121,16 @@ void *a_Jpeg_image(const char *Type, void *P, CA_Callback_t *Call, if (!DicEntry) { /* Let's create an entry for this image... */ DicEntry = a_Dicache_add_entry(web->url); - - /* ... and let the decoder feed it! */ - *Data = Jpeg_new(web->Image, DicEntry->url, DicEntry->version); - *Call = (CA_Callback_t) Jpeg_callback; + DicEntry->DecoderData = + Jpeg_new(web->Image, DicEntry->url, DicEntry->version); } else { - /* Let's feed our client from the dicache */ + /* Repeated image */ a_Dicache_ref(DicEntry->url, DicEntry->version); - *Data = web->Image; - *Call = (CA_Callback_t) a_Dicache_callback; } + DicEntry->Decoder = Jpeg_callback; + *Data = DicEntry->DecoderData; + *Call = (CA_Callback_t) a_Dicache_callback; + return (web->Image->dw); } @@ -330,7 +330,7 @@ static void Jpeg_write(DilloJpeg *jpeg, void *Buf, uint_t BufSize) if (jpeg->state == DILLO_JPEG_READ_BEGIN_SCAN) { if (jpeg_start_output(&jpeg->cinfo, jpeg->cinfo.input_scan_number)) { - a_Dicache_new_scan(jpeg->Image, jpeg->url, jpeg->version); + a_Dicache_new_scan(jpeg->url, jpeg->version); jpeg->state = DILLO_JPEG_READ_IN_SCAN; } } @@ -389,7 +389,7 @@ static void Jpeg_write(DilloJpeg *jpeg, void *Buf, uint_t BufSize) /* out of input */ break; } - a_Dicache_new_scan(jpeg->Image, jpeg->url, jpeg->version); + a_Dicache_new_scan(jpeg->url, jpeg->version); jpeg->state = DILLO_JPEG_READ_IN_SCAN; } } @@ -231,8 +231,9 @@ static void png_progressive_combine_row(png_ptr, png->row_pointers[row_num], new_row); + _MSG("png: row_num=%u previous_row=%u\n", row_num, png->previous_row); if (row_num < png->previous_row) { - a_Dicache_new_scan(png->Image, png->url, png->version); + a_Dicache_new_scan(png->url, png->version); } png->previous_row = row_num; @@ -468,16 +469,16 @@ void *a_Png_image(const char *Type, void *Ptr, CA_Callback_t *Call, if (!DicEntry) { /* Let's create an entry for this image... */ DicEntry = a_Dicache_add_entry(web->url); - - /* ... and let the decoder feed it! */ - *Data = Png_new(web->Image, DicEntry->url, DicEntry->version); - *Call = (CA_Callback_t) Png_callback; + DicEntry->DecoderData = + Png_new(web->Image, DicEntry->url, DicEntry->version); } else { - /* Let's feed our client from the dicache */ + /* Repeated image */ a_Dicache_ref(DicEntry->url, DicEntry->version); - *Data = web->Image; - *Call = (CA_Callback_t) a_Dicache_callback; } + DicEntry->Decoder = Png_callback; + *Data = DicEntry->DecoderData; + *Call = (CA_Callback_t) a_Dicache_callback; + return (web->Image->dw); } |