changeset 703:e2b30a2f4654

[mq]: dicache-cleanup1
author Jorge Arellano Cid <jcid@dillo.org>
date Sat, 27 Dec 2008 14:39:04 -0300
parents 04a873b19301
children eb426b2fc99b
files src/Makefile.am src/dicache.c src/dicache.h src/gif.c src/image.cc src/image.hh src/jpeg.c src/png.c
diffstat 8 files changed, 80 insertions(+), 131 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/Makefile.am	Sat Dec 27 14:39:04 2008 -0300
@@ -89,6 +89,8 @@
 	gif.c \
 	jpeg.c \
 	png.c \
+	imgbuf.cc \
+	imgbuf.hh \
 	image.cc \
 	image.hh \
 	menu.hh \
--- a/src/dicache.c	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/dicache.c	Sat Dec 27 14:39:04 2008 -0300
@@ -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 @@
    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 @@
       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 @@
    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 @@
 
    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 @@
 {
    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 @@
 
    /* 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 @@
 
    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 @@
       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 @@
 {
    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 @@
    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 @@
    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 @@
       /* 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 @@
          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);
--- a/src/dicache.h	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/dicache.h	Sat Dec 27 14:39:04 2008 -0300
@@ -37,6 +37,11 @@
    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_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);
--- a/src/gif.c	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/gif.c	Sat Dec 27 14:39:04 2008 -0300
@@ -176,16 +176,16 @@
    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);
 }
 
--- a/src/image.cc	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/image.cc	Sat Dec 27 14:39:04 2008 -0300
@@ -31,13 +31,6 @@
 
 
 /*
- * 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 @@
 }
 
 /*
- * 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 @@
    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_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_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_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_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;
-}
-
--- a/src/image.hh	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/image.hh	Sat Dec 27 14:39:04 2008 -0300
@@ -69,8 +69,10 @@
 
 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
 }
--- a/src/jpeg.c	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/jpeg.c	Sat Dec 27 14:39:04 2008 -0300
@@ -121,16 +121,16 @@
    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 @@
 
    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 @@
                   /* 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;
             }
          }
--- a/src/png.c	Thu Dec 25 10:04:24 2008 -0300
+++ b/src/png.c	Sat Dec 27 14:39:04 2008 -0300
@@ -231,8 +231,9 @@
 
    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 @@
    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);
 }