aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2008-12-27 14:39:04 -0300
committerJorge Arellano Cid <jcid@dillo.org>2008-12-27 14:39:04 -0300
commit1dc3775146a70648b8806673333fc64a67ffed51 (patch)
tree7da1b29b30492589f9c0ffd5396b6c4476cf99ef
parentc3aeca579c61983bc96d0177806fc48c28c8b825 (diff)
[mq]: dicache-cleanup1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/dicache.c48
-rw-r--r--src/dicache.h8
-rw-r--r--src/gif.c14
-rw-r--r--src/image.cc100
-rw-r--r--src/image.hh4
-rw-r--r--src/jpeg.c18
-rw-r--r--src/png.c17
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);
diff --git a/src/gif.c b/src/gif.c
index 6ea23561..57506590 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -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
}
diff --git a/src/jpeg.c b/src/jpeg.c
index 9e548a7c..8391227f 100644
--- a/src/jpeg.c
+++ b/src/jpeg.c
@@ -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;
}
}
diff --git a/src/png.c b/src/png.c
index e9b0b843..dee8d5b4 100644
--- a/src/png.c
+++ b/src/png.c
@@ -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);
}