work on asynchron pic loading... to get rid of spinning wheels
[vuplus_dvbapp] / lib / gdi / picload.cpp
index 28a8991..2ef901f 100644 (file)
@@ -1,29 +1,57 @@
-#include "picload.h"
-#include "picexif.h"
-
-#include <png.h>
-
+#include <png.h>       // must be included before Python.h because of setjmp
 #include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
+
+#include <lib/gdi/picload.h>
+#include <lib/gdi/picexif.h>
 
 extern "C" {
 #include <jpeglib.h>
-//#include "transupp.h"
+#include <gif_lib.h>
 }
-#include <setjmp.h>
 
-unsigned char *pic_buffer=NULL;
+extern const uint32_t crc32_table[256];
+
+DEFINE_REF(ePicLoad);
+
+static std::string getSize(const char* file)
+{
+       struct stat64 s;
+       if (stat64(file, &s) < 0)
+               return "";
+       char tmp[20];
+       snprintf(tmp, 20, "%ld kB",(long)s.st_size / 1024);
+       return tmp;
+}
+
+static unsigned char *conv24to32(unsigned char *orgin, int size, unsigned char alpha = 0xFF)
+{
+       int s, d;
+       unsigned char *cr = new unsigned char[size * 4];
+       if (cr == NULL)
+       {
+               eDebug("[Picload] Error malloc");
+               return(orgin);
+       }
+
+       for (s = 0, d = 0 ; s < (size * 3); s += 3, d += 4 )
+       {
+               cr[d] = orgin[s];
+               cr[d+1] = orgin[s + 1];
+               cr[d+2] = orgin[s + 2];
+               cr[d+3] = alpha;
+       }
+       delete [] orgin;
+       return(cr);
+}
 
-static unsigned char *simple_resize(unsigned char * orgin, int ox, int oy, int dx, int dy)
+static unsigned char *simple_resize(unsigned char *orgin, int ox, int oy, int dx, int dy)
 {
        unsigned char *cr, *p, *l;
        int i, j, k, ip;
-       cr = new unsigned char[dx * dy * 3]; 
+       cr = new unsigned char[dx * dy * 3];
        if (cr == NULL)
        {
-               printf("[RESIZE] Error: malloc\n");
+               eDebug("[Picload] Error malloc");
                return(orgin);
        }
        l = cr;
@@ -51,7 +79,7 @@ static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx
        cr = new unsigned char[dx * dy * 3];
        if (cr == NULL)
        {
-               printf("[RESIZE] Error: malloc\n");
+               eDebug("[Picload] Error malloc");
                return(orgin);
        }
        p = cr;
@@ -83,109 +111,6 @@ static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx
        return(cr);
 }
 
-//-------------------------------------------------------------------
-
-struct r_jpeg_error_mgr
-{
-       struct jpeg_error_mgr pub;
-       jmp_buf envbuffer;
-};
-
-void jpeg_cb_error_exit(j_common_ptr cinfo)
-{
-       struct r_jpeg_error_mgr *mptr;
-       mptr = (struct r_jpeg_error_mgr *) cinfo->err;
-       (*cinfo->err->output_message) (cinfo);
-       longjmp(mptr->envbuffer, 1);
-}
-
-static int jpeg_save(unsigned char *image_buffer, const char * filename, int quality, int image_height, int image_width)
-{
-       struct jpeg_compress_struct cinfo;
-       struct jpeg_error_mgr jerr;
-       FILE * outfile;         /* target file */
-       JSAMPROW row_pointer[1];/* pointer to JSAMPLE row[s] */
-       int row_stride;         /* physical row width in image buffer */
-       cinfo.err = jpeg_std_error(&jerr);
-       jpeg_create_compress(&cinfo);
-       if ((outfile = fopen(filename, "wb")) == NULL) 
-       {
-               eDebug("[JPEG] can't open %s", filename);
-               return -1;
-       }
-       jpeg_stdio_dest(&cinfo, outfile);
-       cinfo.image_width = image_width;
-       cinfo.image_height = image_height;
-       cinfo.input_components = 3;
-       cinfo.in_color_space = JCS_RGB;
-       jpeg_set_defaults(&cinfo);
-       jpeg_set_quality(&cinfo, quality, TRUE );
-       jpeg_start_compress(&cinfo, TRUE);
-       row_stride = image_width * 3;
-       while (cinfo.next_scanline < cinfo.image_height) 
-       {
-               row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
-               (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
-       }
-       jpeg_finish_compress(&cinfo);
-       fclose(outfile);
-       jpeg_destroy_compress(&cinfo);
-       return 0;
-}
-
-
-static int jpeg_load(const char *filename, int *x, int *y)
-{
-       struct jpeg_decompress_struct cinfo;
-       struct jpeg_decompress_struct *ciptr = &cinfo;
-       struct r_jpeg_error_mgr emgr;
-       FILE *fh;
-
-       if (!(fh = fopen(filename, "rb")))
-               return 0;
-
-       ciptr->err = jpeg_std_error(&emgr.pub);
-       emgr.pub.error_exit = jpeg_cb_error_exit;
-       if (setjmp(emgr.envbuffer) == 1)
-       {
-               jpeg_destroy_decompress(ciptr);
-               fclose(fh);
-               return 0;
-       }
-
-       jpeg_create_decompress(ciptr);
-       jpeg_stdio_src(ciptr, fh);
-       jpeg_read_header(ciptr, TRUE);
-       ciptr->out_color_space = JCS_RGB;
-       ciptr->scale_denom = 1;
-
-       jpeg_start_decompress(ciptr);
-       
-       *x=ciptr->output_width;
-       *y=ciptr->output_height;
-
-       if(ciptr->output_components == 3)
-       {
-               JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
-               pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
-               unsigned char *bp = pic_buffer;
-
-               while (ciptr->output_scanline < ciptr->output_height)
-               {
-                       jpeg_read_scanlines(ciptr, &lb, 1);
-                       memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
-                       bp += ciptr->output_width * ciptr->output_components;
-               }
-       }
-       jpeg_finish_decompress(ciptr);
-       jpeg_destroy_decompress(ciptr);
-       fclose(fh);
-       return 1;
-}
-
 //---------------------------------------------------------------------------------------------
 
 #define BMP_TORASTER_OFFSET 10
@@ -196,41 +121,118 @@ static int jpeg_load(const char *filename, int *x, int *y)
 
 #define fill4B(a) ((4 - ((a) % 4 )) & 0x03)
 
-static int bmp_load(const char *filename,  int *x, int *y)
+struct color {
+       unsigned char red;
+       unsigned char green;
+       unsigned char blue;
+};
+
+static void fetch_pallete(int fd, struct color pallete[], int count)
+{
+       unsigned char buff[4];
+       lseek(fd, BMP_COLOR_OFFSET, SEEK_SET);
+       for (int i = 0; i < count; i++)
+       {
+               read(fd, buff, 4);
+               pallete[i].red = buff[2];
+               pallete[i].green = buff[1];
+               pallete[i].blue = buff[0];
+       }
+}
+
+static unsigned char *bmp_load(const char *file,  int *x, int *y)
 {
        unsigned char buff[4];
+       struct color pallete[256];
 
-       int fd = open(filename, O_RDONLY);
-       if (fd == -1) return 0;
-       if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return 0;
+       int fd = open(file, O_RDONLY);
+       if (fd == -1) return NULL;
+       if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return NULL;
        read(fd, buff, 4);
        *x = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
        read(fd, buff, 4);
        *y = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
-       if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return 0;
+       if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return NULL;
        read(fd, buff, 4);
        int raster = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
-       if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return 0;
+       if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return NULL;
        read(fd, buff, 2);
        int bpp = buff[0] + (buff[1] << 8);
 
-       //printf("x=%d, y=%d,bpp=%d\n",*x, *y, bpp);
-       pic_buffer = new unsigned char[(*x) * (*y) * 3];
+       unsigned char *pic_buffer = new unsigned char[(*x) * (*y) * 3];
        unsigned char *wr_buffer = pic_buffer + (*x) * ((*y) - 1) * 3;
        
        switch (bpp)
        {
+               case 4:
+               {
+                       int skip = fill4B((*x) / 2 + (*x) % 2);
+                       fetch_pallete(fd, pallete, 16);
+                       lseek(fd, raster, SEEK_SET);
+                       unsigned char * tbuffer = new unsigned char[*x / 2 + 1];
+                       if (tbuffer == NULL)
+                               return NULL;
+                       for (int i = 0; i < *y; i++) 
+                       {
+                               read(fd, tbuffer, (*x) / 2 + *x % 2);
+                               int j;
+                               for (j = 0; j < (*x) / 2; j++)
+                               {
+                                       unsigned char c1 = tbuffer[j] >> 4;
+                                       unsigned char c2 = tbuffer[j] & 0x0f;
+                                       *wr_buffer++ = pallete[c1].red;
+                                       *wr_buffer++ = pallete[c1].green;
+                                       *wr_buffer++ = pallete[c1].blue;
+                                       *wr_buffer++ = pallete[c2].red;
+                                       *wr_buffer++ = pallete[c2].green;
+                                       *wr_buffer++ = pallete[c2].blue;
+                               }
+                               if ((*x) % 2)
+                               {
+                                       unsigned char c1 = tbuffer[j] >> 4;
+                                       *wr_buffer++ = pallete[c1].red;
+                                       *wr_buffer++ = pallete[c1].green;
+                                       *wr_buffer++ = pallete[c1].blue;
+                               }
+                               if (skip)
+                                       read(fd, buff, skip);
+                               wr_buffer -= (*x) * 6;
+                       }
+                       break;
+               }
+               case 8:
+               {
+                       int skip = fill4B(*x);
+                       fetch_pallete(fd, pallete, 256);
+                       lseek(fd, raster, SEEK_SET);
+                       unsigned char * tbuffer = new unsigned char[*x];
+                       if (tbuffer == NULL)
+                               return NULL;
+                       for (int i = 0; i < *y; i++)
+                       {
+                               read(fd, tbuffer, *x);
+                               for (int j = 0; j < *x; j++)
+                               {
+                                       wr_buffer[j * 3] = pallete[tbuffer[j]].red;
+                                       wr_buffer[j * 3 + 1] = pallete[tbuffer[j]].green;
+                                       wr_buffer[j * 3 + 2] = pallete[tbuffer[j]].blue;
+                               }
+                               if (skip)
+                                       read(fd, buff, skip);
+                               wr_buffer -= (*x) * 3;
+                       }
+                       break;
+               }
                case 24:
                {
                        int skip = fill4B((*x) * 3);
                        lseek(fd, raster, SEEK_SET);
-                       unsigned char c;
-                       for (int i = 0; i < (*y); i++) 
+                       for (int i = 0; i < (*y); i++)
                        {
                                read(fd, wr_buffer, (*x) * 3);
                                for (int j = 0; j < (*x) * 3 ; j = j + 3)
                                {
-                                       c = wr_buffer[j];
+                                       unsigned char c = wr_buffer[j];
                                        wr_buffer[j] = wr_buffer[j + 2];
                                        wr_buffer[j + 2] = c;
                                }
@@ -241,19 +243,18 @@ static int bmp_load(const char *filename,  int *x, int *y)
                        break;
                }
                default:
-                       return 0;
+                       return NULL;
        }
 
        close(fd);
-       return 1;
+       return(pic_buffer);
 }
 
-//---------------------------------------------------------------------------------------------
+//---------------------------------------------------------------------
 
-static int png_load(const char *filename,  int *x, int *y)
+static unsigned char *png_load(const char *file, int *ox, int *oy)
 {
-       static const png_color_16 my_background = {0, 0, 0, 0, 0};
-
+       //static const png_color_16 my_background = {0, 0, 0, 0, 0};
        png_structp png_ptr;
        png_infop info_ptr;
        png_uint_32 width, height;
@@ -263,17 +264,17 @@ static int png_load(const char *filename,  int *x, int *y)
        png_byte * fbptr;
        FILE * fh;
 
-       if (!(fh = fopen(filename, "rb"))) return 0;
+       if (!(fh = fopen(file, "rb"))) return NULL;
 
        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (png_ptr == NULL)
-               return 0;
+               return NULL;
        info_ptr = png_create_info_struct(png_ptr);
        if (info_ptr == NULL)
        {
                png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
                fclose(fh); 
-               return 0;
+               return NULL;
        }
 
        if (setjmp(png_ptr->jmpbuf))
@@ -288,248 +289,729 @@ static int png_load(const char *filename,  int *x, int *y)
        png_read_info(png_ptr, info_ptr);
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
 
-       if (color_type == PNG_COLOR_TYPE_PALETTE)
-       {
-               png_set_palette_to_rgb(png_ptr);
-               png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-       }
-
+       if ((color_type == PNG_COLOR_TYPE_PALETTE)||(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)||(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+               png_set_expand(png_ptr);
+       if (bit_depth == 16)
+               png_set_strip_16(png_ptr);
        if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-       {
                png_set_gray_to_rgb(png_ptr);
-               png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-       }
-
-       if (color_type & PNG_COLOR_MASK_ALPHA)
-               png_set_strip_alpha(png_ptr);
-
-       if (bit_depth < 8)      png_set_packing(png_ptr);
-       if (bit_depth == 16)    png_set_strip_16(png_ptr);
 
        number_passes = png_set_interlace_handling(png_ptr);
        png_read_update_info(png_ptr, info_ptr);
 
-       if (width * 3 != png_get_rowbytes(png_ptr, info_ptr))
+       int bpp =  png_get_rowbytes(png_ptr, info_ptr)/width;
+       if ((bpp !=4) && (bpp !=3))
        {
                eDebug("[PNG] Error processing");
                return 0;
        }
-       
-       pic_buffer = new unsigned char[width * height * 3];
-       *x=width;
-       *y=height;
+
+       if (width * height > 1000000) // 1000x1000 or equiv.
+       {
+               eDebug("[png_load] image size is %d x %d, which is \"too large\".", (int)width, (int)height);
+               png_read_end(png_ptr, info_ptr);
+               png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+               fclose(fh);
+               return 0;
+       }
+
+       unsigned char *pic_buffer = new unsigned char[width * height * bpp];
+       *ox=width;
+       *oy=height;
 
        for(pass = 0; pass < number_passes; pass++)
        {
                fbptr = (png_byte *)pic_buffer;
-               for (i = 0; i < height; i++, fbptr += width * 3)
+               for (i = 0; i < height; i++, fbptr += width * bpp)
                        png_read_row(png_ptr, fbptr, NULL);
        }
        png_read_end(png_ptr, info_ptr);
        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
        fclose(fh);
-       return 1;
+       return(pic_buffer);
 }
 
-//---------------------------------------------------------------------------------------------
+//-------------------------------------------------------------------
 
-PyObject *getExif(const char *filename)
+struct r_jpeg_error_mgr
 {
-       PyObject *list = PyList_New(0);
-       Cexif *m_exif = new Cexif();
-       if(m_exif->DecodeExif(filename))
+       struct jpeg_error_mgr pub;
+       jmp_buf envbuffer;
+};
+
+void jpeg_cb_error_exit(j_common_ptr cinfo)
+{
+       struct r_jpeg_error_mgr *mptr;
+       mptr = (struct r_jpeg_error_mgr *) cinfo->err;
+       (*cinfo->err->output_message) (cinfo);
+       longjmp(mptr->envbuffer, 1);
+}
+
+static unsigned char *jpeg_load(const char *file, int *ox, int *oy)
+{
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_decompress_struct *ciptr = &cinfo;
+       struct r_jpeg_error_mgr emgr;
+       FILE *fh;
+       unsigned char *pic_buffer=NULL;
+
+       if (!(fh = fopen(file, "rb")))
+               return NULL;
+
+       ciptr->err = jpeg_std_error(&emgr.pub);
+       emgr.pub.error_exit = jpeg_cb_error_exit;
+       if (setjmp(emgr.envbuffer) == 1)
        {
-               
-               if(m_exif->m_exifinfo->IsExif)
+               jpeg_destroy_decompress(ciptr);
+               fclose(fh);
+               return NULL;
+       }
+
+       jpeg_create_decompress(ciptr);
+       jpeg_stdio_src(ciptr, fh);
+       jpeg_read_header(ciptr, TRUE);
+       ciptr->out_color_space = JCS_RGB;
+       ciptr->scale_denom = 1;
+
+       jpeg_start_decompress(ciptr);
+       
+       *ox=ciptr->output_width;
+       *oy=ciptr->output_height;
+
+       if(ciptr->output_components == 3)
+       {
+               JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
+               pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
+               unsigned char *bp = pic_buffer;
+
+               while (ciptr->output_scanline < ciptr->output_height)
                {
-                       char tmp[256];
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->Version));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->CameraMake));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->CameraModel));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->DateTime));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->Comments));
-                       PyList_Append(list, PyString_FromFormat("%d x %d", m_exif->m_exifinfo->Width, m_exif->m_exifinfo->Height));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->Orientation));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->MeteringMode));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->ExposureProgram));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->LightSource));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->FlashUsed));
-                       PyList_Append(list, PyString_FromFormat("%d", m_exif->m_exifinfo->CompressionLevel));
-                       PyList_Append(list, PyString_FromFormat("%d", m_exif->m_exifinfo->ISOequivalent));
-                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->Xresolution);
-                       PyList_Append(list, PyString_FromString(tmp));
-                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->Yresolution);
-                       PyList_Append(list, PyString_FromString(tmp));
-                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->ResolutionUnit));
-                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->Brightness);
-                       PyList_Append(list, PyString_FromString(tmp));
-                       sprintf(tmp, "%.5f sec.", m_exif->m_exifinfo->ExposureTime);
-                       PyList_Append(list, PyString_FromString(tmp));
-                       sprintf(tmp, "%.5f", m_exif->m_exifinfo->ExposureBias);
-                       PyList_Append(list, PyString_FromString(tmp));
-                       sprintf(tmp, "%.5f", m_exif->m_exifinfo->Distance);
-                       PyList_Append(list, PyString_FromString(tmp));
-                       sprintf(tmp, "%.5f", m_exif->m_exifinfo->CCDWidth);
-                       PyList_Append(list, PyString_FromString(tmp));
-                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->ApertureFNumber);
-                       PyList_Append(list, PyString_FromString(tmp));
+                       jpeg_read_scanlines(ciptr, &lb, 1);
+                       memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
+                       bp += ciptr->output_width * ciptr->output_components;
                }
-               else    PyList_Append(list, PyString_FromString(m_exif->m_szLastError));
+       }
+       jpeg_finish_decompress(ciptr);
+       jpeg_destroy_decompress(ciptr);
+       fclose(fh);
+       return(pic_buffer);
+}
 
-               m_exif->ClearExif();
+
+static int jpeg_save(const char * filename, int ox, int oy, unsigned char *pic_buffer)
+{
+       struct jpeg_compress_struct cinfo;
+       struct jpeg_error_mgr jerr;
+       FILE * outfile;         
+       JSAMPROW row_pointer[1];
+       int row_stride;         
+       cinfo.err = jpeg_std_error(&jerr);
+       jpeg_create_compress(&cinfo);
+       if ((outfile = fopen(filename, "wb")) == NULL) 
+       {
+               eDebug("[Picload] jpeg can't open %s", filename);
+               return 1;
        }
-       else    PyList_Append(list, PyString_FromString(m_exif->m_szLastError));
+       eDebug("[Picload] save Thumbnail... %s",filename);
 
-       delete m_exif;
-       
-       return list;
+       jpeg_stdio_dest(&cinfo, outfile);
+       cinfo.image_width = ox;
+       cinfo.image_height = oy;
+       cinfo.input_components = 3;
+       cinfo.in_color_space = JCS_RGB;
+       jpeg_set_defaults(&cinfo);
+       jpeg_set_quality(&cinfo, 70, TRUE );
+       jpeg_start_compress(&cinfo, TRUE);
+       row_stride = ox * 3;
+       while (cinfo.next_scanline < cinfo.image_height) 
+       {
+               row_pointer[0] = & pic_buffer[cinfo.next_scanline * row_stride];
+               (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+       }
+       jpeg_finish_compress(&cinfo);
+       fclose(outfile);
+       jpeg_destroy_compress(&cinfo);
+       return 0;
 }
 
-//---------------------------------------------------------------------------------------------
+//-------------------------------------------------------------------
 
-int loadPic(ePtr<gPixmap> &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile)
+inline void m_rend_gif_decodecolormap(unsigned char *cmb, unsigned char *rgbb, ColorMapObject *cm, int s, int l)
 {
-       result = 0;
-       int ox=0, oy=0, imx, imy;
-       pic_buffer=NULL;
-       bool cache=false;
-
-       if(cachefile.length())
-       {
-               cache = true;
-               if(jpeg_load(cachefile.c_str(), &ox, &oy))
-                       eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy);
-       }
-
-       if(pic_buffer==NULL)
-       {
-               unsigned int pos = filename.find_last_of(".");
-               if (pos == std::string::npos)
-                       pos = filename.length() - 1;
-               std::string ext = filename.substr(pos);
-               std::transform(ext.begin(), ext.end(), ext.begin(), (int(*)(int)) toupper);
-               if(ext == ".JPEG" || ext == ".JPG")
-                       jpeg_load(filename.c_str(), &ox, &oy);
-               else if(ext == ".BMP")
-                       bmp_load(filename.c_str(), &ox, &oy);
-               else if(ext == ".PNG")
-                       png_load(filename.c_str(), &ox, &oy);
-               else
+       GifColorType *cmentry;
+       int i;
+       for (i = 0; i < l; i++)
+       {
+               cmentry = &cm->Colors[cmb[i]];
+               *(rgbb++) = cmentry->Red;
+               *(rgbb++) = cmentry->Green;
+               *(rgbb++) = cmentry->Blue;
+       }
+}
+
+static unsigned char *gif_load(const char *file, int *ox, int *oy)
+{
+       unsigned char *pic_buffer = NULL;
+       int px, py, i, j, ibxs;
+       unsigned char *fbptr;
+       unsigned char *lb=NULL;
+       unsigned char *slb=NULL;
+       GifFileType *gft;
+       GifRecordType rt;
+       GifByteType *extension;
+       ColorMapObject *cmap;
+       int cmaps;
+       int extcode;
+       
+       gft = DGifOpenFileName(file);
+       if (gft == NULL) 
+               return NULL;
+       do
+       {
+               if (DGifGetRecordType(gft, &rt) == GIF_ERROR)
+                       goto ERROR_R;
+               switch(rt)
                {
-                       eDebug("[PIC] <format not supportet>");
-                       return 0;
+                       case IMAGE_DESC_RECORD_TYPE:
+                               if (DGifGetImageDesc(gft) == GIF_ERROR)
+                                       goto ERROR_R;
+                               *ox = px = gft->Image.Width;
+                               *oy = py = gft->Image.Height;
+                               pic_buffer = new unsigned char[px * py * 3];
+                               lb = (unsigned char *)malloc(px * 3);
+                               slb = (unsigned char *) malloc(px);
+
+                               if (lb != NULL && slb != NULL)
+                               {
+                                       cmap = (gft->Image.ColorMap ? gft->Image.ColorMap : gft->SColorMap);
+                                       cmaps = cmap->ColorCount;
+
+                                       ibxs = ibxs * 3;
+                                       fbptr = pic_buffer;
+                                       if (!(gft->Image.Interlace))
+                                       {
+                                               for (i = 0; i < py; i++, fbptr += px * 3)
+                                               {
+                                                       if (DGifGetLine(gft, slb, px) == GIF_ERROR)
+                                                               goto ERROR_R;
+                                                       m_rend_gif_decodecolormap(slb, lb, cmap, cmaps, px);
+                                                       memcpy(fbptr, lb, px * 3);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               for (j = 0; j < 4; j++)
+                                               {
+                                                       fbptr = pic_buffer;
+                                                       for (i = 0; i < py; i++, fbptr += px * 3)
+                                                       {
+                                                               if (DGifGetLine(gft, slb, px) == GIF_ERROR)
+                                                                       goto ERROR_R;
+                                                               m_rend_gif_decodecolormap(slb, lb, cmap, cmaps, px);
+                                                               memcpy(fbptr, lb, px * 3);
+                                                       }
+                                               }
+                                       }
+                               }
+                               if (lb)
+                               {
+                                       free(lb);
+                                       lb=NULL;
+                               }
+                               if (slb)
+                               {
+                                       free(slb);
+                                       slb=NULL;
+                               }
+                               break;
+                       case EXTENSION_RECORD_TYPE:
+                               if (DGifGetExtension(gft, &extcode, &extension) == GIF_ERROR)
+                                       goto ERROR_R;
+                               while (extension != NULL)
+                                       if (DGifGetExtensionNext(gft, &extension) == GIF_ERROR)
+                                               goto ERROR_R;
+                               break;
+                       default:
+                               break;
                }
+       }
+       while (rt != TERMINATE_RECORD_TYPE);
+
+       DGifCloseFile(gft);
+       return(pic_buffer);
+ERROR_R:
+       eDebug("[Picload] <Error gif>");
+       if (lb)         free(lb);
+       if (slb)        free(slb);
+       DGifCloseFile(gft);
+       return NULL;
+}
+
+//---------------------------------------------------------------------------------------------
+
+ePicLoad::ePicLoad()
+       :msg_thread(this,1), msg_main(eApp,1)
+{
+       CONNECT(msg_thread.recv_msg, ePicLoad::gotMessage);
+       CONNECT(msg_main.recv_msg, ePicLoad::gotMessage);
        
-               eDebug("[FULLPIC] x-size=%d, y-size=%d", ox, oy);
+       threadrunning = false;
+       m_filepara = NULL;
+       m_conf.max_x = 0;
+       m_conf.max_y = 0;
+       m_conf.aspect_ratio = 1.066400; //4:3
+       m_conf.usecache = false;
+       m_conf.resizetype = 1;
+       memset(m_conf.background,0x00,sizeof(m_conf.background));
+       m_conf.thumbnailsize = 180;
+}
+
+ePicLoad::~ePicLoad()
+{
+       msg_thread.send(Message(Message::quit));
+       kill();
+
+       if(m_filepara != NULL)
+               delete m_filepara;
+}
+
+
+void ePicLoad::thread()
+{
+       hasStarted();
+       nice(4);
+       runLoop();
+}
+
+void ePicLoad::decodePic()
+{
+       eDebug("[Picload] decode picture... %s",m_filepara->file);
+       
+       switch(m_filepara->id)
+       {
+               case F_PNG:     m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy);  break;
+               case F_JPEG:    m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+               case F_BMP:     m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy);  break;
+               case F_GIF:     m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy);  break;
+       }
+       
+       if(m_filepara->pic_buffer != NULL)
+       {
+               resizePic();
+       }
+}
 
-               if(pic_buffer==NULL)
-                       return 0;
+void ePicLoad::decodeThumb()
+{
+       eDebug("[Picload] get Thumbnail... %s",m_filepara->file);
 
-               double aspect_ratio;
-               switch(aspect)
+       bool exif_thumbnail = false;
+       bool cachefile_found = false;
+       std::string cachefile = "";
+       std::string cachedir = "/.Thumbnails";
+       
+       if(m_filepara->id == F_JPEG)
+       {
+               Cexif *exif = new Cexif;
+               if(exif->DecodeExif(m_filepara->file, 1))
                {
-                       case 1:         aspect_ratio = 1.777 / ((double)720/576); break; //16:9
-                       case 2:         aspect_ratio = 1.600 / ((double)720/576); break; //16:10
-                       //case 3:       aspect_ratio = 1.250 / ((double)720/576); break; //5:4
-                       default:        aspect_ratio = 1.333 / ((double)720/576); //4:3
+                       if(exif->m_exifinfo->IsExif)
+                       {
+                               if(exif->m_exifinfo->Thumnailstate==2)
+                               {
+                                       m_filepara->file = strdup(THUMBNAILTMPFILE);
+                                       exif_thumbnail = true;
+                                       eDebug("[Picload] Exif Thumbnail found");
+                               }
+                               m_filepara->addExifInfo(exif->m_exifinfo->CameraMake);
+                               m_filepara->addExifInfo(exif->m_exifinfo->CameraModel);
+                               m_filepara->addExifInfo(exif->m_exifinfo->DateTime);
+                               char buf[20];
+                               snprintf(buf, 20, "%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height);
+                               m_filepara->addExifInfo(buf);
+                       }
+                       exif->ClearExif();
                }
-
-               if((aspect_ratio * oy * w / ox) <= h)
+               delete exif;
+       }
+       
+       if((! exif_thumbnail) && m_conf.usecache)
+       {
+               if(FILE *f=fopen(m_filepara->file, "rb"))
                {
-                       imx = w;
-                       imy = (int)(aspect_ratio*oy*w/ox);
+                       int c;
+                       int count = 1024*100;
+                       unsigned long crc32 = 0;
+                       char crcstr[9];*crcstr=0;
+
+                       while ((c=getc(f))!=EOF)
+                       {
+                               crc32 = crc32_table[((crc32) ^ (c)) & 0xFF] ^ ((crc32) >> 8);
+                               if(--count < 0) break;
+                       }
+       
+                       fclose(f);
+                       crc32 = ~crc32;
+                       sprintf(crcstr, "%08lX", crc32);
+               
+                       cachedir = m_filepara->file;
+                       unsigned int pos = cachedir.find_last_of("/");
+                       if (pos != std::string::npos)
+                               cachedir = cachedir.substr(0, pos) + "/.Thumbnails";
+                       
+                       cachefile = cachedir + std::string("/pc_") + crcstr;
+                       if(!access(cachefile.c_str(), R_OK))
+                       {
+                               cachefile_found = true;
+                               m_filepara->file = strdup(cachefile.c_str());
+                               m_filepara->id = F_JPEG;
+                               eDebug("[Picload] Cache File found");
+                       }
                }
-               else
+       }
+
+       switch(m_filepara->id)
+       {
+               case F_PNG:     m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy);  break;
+               case F_JPEG:    m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+               case F_BMP:     m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy);  break;
+               case F_GIF:     m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy);  break;
+       }
+       
+       if(exif_thumbnail)
+               ::unlink(THUMBNAILTMPFILE);
+       
+       if(m_filepara->pic_buffer != NULL)
+       {
+               //save cachefile
+               if(m_conf.usecache && (! exif_thumbnail) && (! cachefile_found))
                {
-                       imx = (int)((1.0/aspect_ratio)*ox*h/oy);
-                       imy = h;
+                       if(access(cachedir.c_str(), R_OK))
+                               ::mkdir(cachedir.c_str(), 0755);
+                       
+                       //resize for Thumbnail
+                       int imx, imy;
+                       if (m_filepara->ox <= m_filepara->oy)
+                       {
+                               imy = m_conf.thumbnailsize;
+                               imx = (int)( (m_conf.thumbnailsize * ((double)m_filepara->ox)) / ((double)m_filepara->oy) );
+                       }
+                       else
+                       {
+                               imx = m_conf.thumbnailsize;
+                               imy = (int)( (m_conf.thumbnailsize * ((double)m_filepara->oy)) / ((double)m_filepara->ox) );
+                       }
+
+                       m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy);
+                       m_filepara->ox = imx;
+                       m_filepara->oy = imy;
+
+                       if(jpeg_save(cachefile.c_str(), m_filepara->ox, m_filepara->oy, m_filepara->pic_buffer))
+                               eDebug("[Picload] error saving cachefile");
                }
 
-               if(resize_mode) pic_buffer = color_resize(pic_buffer, ox, oy, imx, imy);
-               else            pic_buffer = simple_resize(pic_buffer, ox, oy, imx, imy);
+               resizePic();
+       }
+}
+
+void ePicLoad::resizePic()
+{
+       int imx, imy;
 
-               ox = imx;
-               oy = imy;
+       if((m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox) <= m_filepara->max_y)
+       {
+               imx = m_filepara->max_x;
+               imy = (int)(m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox);
+       }
+       else
+       {
+               imx = (int)((1.0/m_conf.aspect_ratio) * m_filepara->ox * m_filepara->max_y / m_filepara->oy);
+               imy = m_filepara->max_y;
+       }
                
-               if(cache)
+       if(m_conf.resizetype)
+               m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy);
+       else
+               m_filepara->pic_buffer = simple_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy);
+
+       m_filepara->ox = imx;
+       m_filepara->oy = imy;
+}
+
+void ePicLoad::gotMessage(const Message &msg)
+{
+       switch (msg.type)
+       {
+               case Message::decode_Pic:
+                       decodePic();
+                       msg_main.send(Message(Message::decode_finished));
+                       break;
+               case Message::decode_Thumb:
+                       decodeThumb();
+                       msg_main.send(Message(Message::decode_finished));
+                       break;
+               case Message::quit: // called from decode thread
+                       eDebug("[Picload] decode thread ... got quit msg");
+                       quit(0);
+                       break;
+               case Message::decode_finished: // called from main thread
+                       //eDebug("[Picload] decode finished... %s", m_filepara->file);
+                       threadrunning=false;
+                       if(m_filepara->callback)
+                       {
+                               PictureData(m_filepara->picinfo.c_str());
+                       }
+                       else
+                       {
+                               if(m_filepara != NULL)
+                               {
+                                       delete m_filepara;
+                                       m_filepara = NULL;
+                               }
+                       }
+                       break;
+               default:
+                       eDebug("unhandled thread message");
+       }
+}
+
+int ePicLoad::startThread(int what, const char *file, int x, int y)
+{
+       if(threadrunning && m_filepara != NULL)
+       {
+               eDebug("[Picload] thread running");
+               m_filepara->callback = false;
+               return 1;
+       }
+       
+       if(m_filepara != NULL)
+       {
+               delete m_filepara;
+               m_filepara = NULL;
+       }
+       
+       int file_id = -1;
+       unsigned char id[10];
+       int fd = ::open(file, O_RDONLY);
+       if (fd == -1) return 1;
+       ::read(fd, id, 10);
+       ::close(fd);
+
+       if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G')                        file_id = F_PNG;
+       else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F')   file_id = F_JPEG;
+       else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff)                file_id = F_JPEG;
+       else if(id[0] == 'B' && id[1] == 'M' )                                  file_id = F_BMP;
+       else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F')                   file_id = F_GIF;
+       
+       if(file_id < 0)
+       {
+               eDebug("[Picload] <format not supportet>");
+               return 1;
+       }
+
+       m_filepara = new Cfilepara(file, file_id, getSize(file));
+       x > 0 ? m_filepara->max_x = x : m_filepara->max_x = m_conf.max_x;
+       y > 0 ? m_filepara->max_y = y : m_filepara->max_y = m_conf.max_y;
+       
+       if(m_filepara->max_x <= 0 || m_filepara->max_y <= 0)
+       {
+               delete m_filepara;
+               m_filepara = NULL;
+               eDebug("[Picload] <error in Para>");
+               return 1;
+       }
+       
+       threadrunning=true;
+       if(what==1)
+               msg_thread.send(Message(Message::decode_Pic));
+       else
+               msg_thread.send(Message(Message::decode_Thumb));
+       run();
+       return 0;
+}
+
+RESULT ePicLoad::startDecode(const char *file, int x, int y)
+{
+       return startThread(1, file, x, y);
+}
+
+RESULT ePicLoad::getThumbnail(const char *file, int x, int y)
+{
+       return startThread(0, file, x, y);
+}
+
+RESULT ePicLoad::setPara(PyObject *val)
+{
+       if (!PyList_Check(val))
+               return 0;
+       if (PyList_Size(val) < 6)
+               return 0;
+
+       m_conf.max_x            = PyInt_AsLong( PyList_GET_ITEM(val, 0));
+       m_conf.max_y            = PyInt_AsLong( PyList_GET_ITEM(val, 1));
+       m_conf.aspect_ratio     = PyFloat_AsDouble( PyList_GET_ITEM(val, 2));
+       m_conf.usecache         = PyInt_AsLong( PyList_GET_ITEM(val, 3));
+       m_conf.resizetype       = PyInt_AsLong( PyList_GET_ITEM(val, 4));
+       const char *bg_str      = PyString_AsString( PyList_GET_ITEM(val, 5));
+       
+       if(bg_str[0] == '#' && strlen(bg_str)==9)
+       {
+               int bg = strtoul(bg_str+1, NULL, 16);
+               m_conf.background[0] = bg&0xFF;         //BB
+               m_conf.background[1] = (bg>>8)&0xFF;    //GG
+               m_conf.background[2] = (bg>>16)&0xFF;   //RR
+               m_conf.background[3] = bg>>24;          //AA
+       }
+       
+       eDebug("[Picload] setPara max-X=%d max-Y=%d aspect_ratio=%lf cache=%d resize=%d bg=#%02X%02X%02X%02X", m_conf.max_x, m_conf.max_y, m_conf.aspect_ratio, (int)m_conf.usecache, (int)m_conf.resizetype, m_conf.background[3], m_conf.background[2], m_conf.background[1], m_conf.background[0]);
+       return 1;
+}
+
+PyObject *ePicLoad::getInfo(const char *filename)
+{
+       ePyObject list;
+       
+       Cexif *exif = new Cexif;
+       if(exif->DecodeExif(filename))
+       {
+               if(exif->m_exifinfo->IsExif)
                {
-                       jpeg_save(pic_buffer, cachefile.c_str(), 50, oy, ox);
-                       eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy);
+                       char tmp[256];
+                       int pos=0;
+                       list = PyList_New(23);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(filename));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->Version));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->CameraMake));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->CameraModel));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->DateTime));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromFormat("%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->FlashUsed));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->Orientation));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->Comments));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->MeteringMode));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->ExposureProgram));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->LightSource));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromFormat("%d", exif->m_exifinfo->CompressionLevel));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromFormat("%d", exif->m_exifinfo->ISOequivalent));
+                       sprintf(tmp, "%.2f", exif->m_exifinfo->Xresolution);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
+                       sprintf(tmp, "%.2f", exif->m_exifinfo->Yresolution);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(exif->m_exifinfo->ResolutionUnit));
+                       sprintf(tmp, "%.2f", exif->m_exifinfo->Brightness);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f sec.", exif->m_exifinfo->ExposureTime);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f", exif->m_exifinfo->ExposureBias);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f", exif->m_exifinfo->Distance);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f", exif->m_exifinfo->CCDWidth);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
+                       sprintf(tmp, "%.2f", exif->m_exifinfo->ApertureFNumber);
+                       PyList_SET_ITEM(list, pos++,  PyString_FromString(tmp));
                }
-               
+               else
+               {
+                       list = PyList_New(2);
+                       PyList_SET_ITEM(list, 0, PyString_FromString(filename));
+                       PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError));
+               }
+               exif->ClearExif();
        }
+       else
+       {
+               list = PyList_New(2);
+               PyList_SET_ITEM(list, 0, PyString_FromString(filename));
+               PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError));
+       }
+       delete exif;
+
+       return list ? (PyObject*)list : (PyObject*)PyList_New(0);
+}
 
+int ePicLoad::getData(ePtr<gPixmap> &result)
+{
+       if(m_filepara->pic_buffer == NULL) return 0;
+       
+       m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy);
        
-       result=new gPixmap(eSize(w, h), 32);
+       result=new gPixmap(eSize(m_filepara->max_x, m_filepara->max_y), 32);
        gSurface *surface = result->surface;
        int a=0, b=0;
        int nc=0, oc=0;
        int o_y=0, u_y=0, v_x=0, h_x=0;
-       unsigned char clear[4] = {0x00,0x00,0x00,0x00};
-       if(background)  clear[3]=0xFF;
-       unsigned char *tmp_buffer = new unsigned char[4];
 
-       if(oy < h)
+       unsigned char *tmp_buffer=((unsigned char *)(surface->data));
+       
+       if(m_filepara->oy < m_filepara->max_y)
        {
-               o_y=(h-oy)/2;
-               u_y=h-oy-o_y;
+               o_y = (m_filepara->max_y - m_filepara->oy) / 2;
+               u_y = m_filepara->max_y - m_filepara->oy - o_y;
        }
-       if(ox < w)
+       if(m_filepara->ox < m_filepara->max_x)
        {
-               v_x=(w-ox)/2;
-               h_x=w-ox-v_x;
+               v_x = (m_filepara->max_x - m_filepara->ox) / 2;
+               h_x = m_filepara->max_x - m_filepara->ox - v_x;
        }
        
-       //eDebug("o_y=%d u_y=%d v_x=%d h_x=%d", o_y, u_y, v_x, h_x);
-
-       if(oy < h)
-               for(a=0; a<(o_y*ox)+1; a++, nc+=4)
+       if(m_filepara->oy < m_filepara->max_y)
+       {
+               for(a=0; a<(o_y*m_filepara->ox); a++, nc+=4)
                {
-                       memcpy(tmp_buffer, clear, sizeof(clear));
                        tmp_buffer=((unsigned char *)(surface->data)) + nc;
+                       memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
                }
+       }
        
-       for(a=0; a<oy; a++)
+       for(a=0; a<m_filepara->oy; a++)
        {
-               if(ox < w)
+               if(m_filepara->ox < m_filepara->max_x)
+               {
                        for(b=0; b<v_x; b++, nc+=4)
                        {
-                               memcpy(tmp_buffer, clear, sizeof(clear));
                                tmp_buffer=((unsigned char *)(surface->data)) + nc;
+                               memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
                        }
+               }
 
-               for(b=0; b<(ox*3); b+=3, nc+=4)
+               for(b=0; b<(m_filepara->ox*4); b+=4, nc+=4)
                {
-                       tmp_buffer[3]=0xFF;
-                       tmp_buffer[2]=pic_buffer[oc++];
-                       tmp_buffer[1]=pic_buffer[oc++];
-                       tmp_buffer[0]=pic_buffer[oc++];
-
                        tmp_buffer=((unsigned char *)(surface->data)) + nc;
+                       tmp_buffer[2] = m_filepara->pic_buffer[oc++];
+                       tmp_buffer[1] = m_filepara->pic_buffer[oc++];
+                       tmp_buffer[0] = m_filepara->pic_buffer[oc++];
+                       tmp_buffer[3] = m_filepara->pic_buffer[oc++];
                }
                
-               if(ox < w)
+               if(m_filepara->ox < m_filepara->max_x)
+               {
                        for(b=0; b<h_x; b++, nc+=4)
                        {
-                               memcpy(tmp_buffer, clear, sizeof(clear));
                                tmp_buffer=((unsigned char *)(surface->data)) + nc;
+                               memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
                        }
+               }
        }
-
-       if(oy < h)
-               for(a=0; a<(u_y*ox)+1; a++, nc+=4)
+       
+       if(m_filepara->oy < m_filepara->max_y)
+       {
+               for(a=0; a<(u_y*m_filepara->ox); a++, nc+=4)
                {
-                       memcpy(tmp_buffer, clear, sizeof(clear));
                        tmp_buffer=((unsigned char *)(surface->data)) + nc;
+                       memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
                }
-       
-       //eDebug("[PIC] buffer=%d, nc=%d oc=%d ox=%d, oy=%d",w*h*4, nc, oc, ox, oy);
+       }
        
        surface->clut.data=0;
        surface->clut.colors=0;
        surface->clut.start=0;
-       
-       delete [] pic_buffer;
+
+       delete m_filepara;
+       m_filepara = NULL;
 
        return 0;
 }