Merge branch 'bug_414_spinner_recording_paths' into experimental
[enigma2.git] / lib / gdi / epng.cpp
index 4666cdf305c06a126a356d3910d7ae41e98005ff..972a89d374cf647f6eb667db5e90da730b6c85ea 100644 (file)
@@ -70,9 +70,7 @@ int loadPNG(ePtr<gPixmap> &result, const char *filename)
        
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
        
-//     eDebug("%s: %dx%dx%d png, %d", filename, (int)width, (int)height, (int)bit_depth, color_type);
-       
-       if (color_type != 6)
+       if (color_type == PNG_COLOR_TYPE_GRAY || color_type & PNG_COLOR_MASK_PALETTE)
        {
                result=new gPixmap(eSize(width, height), bit_depth);
                gSurface *surface = result->surface;
@@ -117,8 +115,10 @@ int loadPNG(ePtr<gPixmap> &result, const char *filename)
                }
                surface->clut.start=0;
                png_read_end(png_ptr, end_info);
-       } else
+       } else {
                result=0;
+               eDebug("%s: %dx%dx%d png, %d", filename, (int)width, (int)height, (int)bit_depth, color_type);
+       }
 
        png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);
        fclose(fp);
@@ -140,14 +140,14 @@ my_error_exit (j_common_ptr cinfo)
        longjmp(myerr->setjmp_buffer, 1);
 }
 
-int loadJPG(ePtr<gPixmap> &result, const char *filename, gPixmap *alpha)
+int loadJPG(ePtr<gPixmap> &result, const char *filename, ePtr<gPixmap> alpha)
 {
        struct jpeg_decompress_struct cinfo;
        struct my_error_mgr jerr;
        FILE *infile;
        JSAMPARRAY buffer;
        int row_stride;
-       infile = fopen(filename, "r");
+       infile = fopen(filename, "rb");
        result = 0;
 
        if (alpha)
@@ -172,6 +172,10 @@ int loadJPG(ePtr<gPixmap> &result, const char *filename, gPixmap *alpha)
        jpeg_create_decompress(&cinfo);
        jpeg_stdio_src(&cinfo, infile);
        (void) jpeg_read_header(&cinfo, TRUE);
+       cinfo.out_color_space = JCS_RGB;
+       cinfo.scale_denom = 1;
+
+       (void) jpeg_start_decompress(&cinfo);
 
        int grayscale = cinfo.output_components == 1;
 
@@ -191,27 +195,28 @@ int loadJPG(ePtr<gPixmap> &result, const char *filename, gPixmap *alpha)
 
        result = new gPixmap(eSize(cinfo.output_width, cinfo.output_height), grayscale ? 8 : 32);
 
-       (void) jpeg_start_decompress(&cinfo);
        row_stride = cinfo.output_width * cinfo.output_components;
        buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
        while (cinfo.output_scanline < cinfo.output_height) {
+               int y = cinfo.output_scanline;
                (void) jpeg_read_scanlines(&cinfo, buffer, 1);
-               unsigned char *dst = ((unsigned char*)result->surface->data) + result->surface->stride * cinfo.output_scanline;
+               unsigned char *dst = ((unsigned char*)result->surface->data) + result->surface->stride * y;
                unsigned char *src = (unsigned char*)buffer[0];
-               unsigned char *palpha = alpha ? ((unsigned char*)alpha->surface->data + alpha->surface->stride * cinfo.output_scanline) : 0;
+               unsigned char *palpha = alpha ? ((unsigned char*)alpha->surface->data + alpha->surface->stride * y) : 0;
                if (grayscale)
-                       memcpy(dst, src, row_stride);
+                       memcpy(dst, src, cinfo.output_width);
                else
                {
                        int x;
                        for (x = 0; x < (int)cinfo.output_width; ++x)
                        {
-                               *dst++ = *src++;
-                               *dst++ = *src++;
-                               *dst++ = *src++;
-                               if (alpha)
+                               *dst++ = src[2];
+                               *dst++ = src[1];
+                               *dst++ = src[0];
+                               src += 3;
+                               if (palpha)
                                        *dst++ = *palpha++;
-                               else
+                               else 
                                        *dst++ = 0xFF;
                        }
                }
@@ -224,6 +229,8 @@ int loadJPG(ePtr<gPixmap> &result, const char *filename, gPixmap *alpha)
 
 int savePNG(const char *filename, gPixmap *pixmap)
 {
+
+       eDebug("\33[33m %s \33[0m",filename);
        FILE *fp=fopen(filename, "wb");
        if (!fp)
                return -1;
@@ -249,6 +256,11 @@ int savePNG(const char *filename, gPixmap *pixmap)
                unlink(filename);
                return -3;
        }
+
+       png_set_IHDR(png_ptr, info_ptr, surface->x, surface->y, surface->bpp/surface->bypp, 
+               PNG_COLOR_TYPE_RGB_ALPHA, 
+               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
        if (setjmp(png_ptr->jmpbuf))
        {
                eDebug("error :/");
@@ -261,29 +273,35 @@ int savePNG(const char *filename, gPixmap *pixmap)
        png_set_filter(png_ptr, 0, PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_PAETH);
        png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
 
-       png_set_IHDR(png_ptr, info_ptr, surface->x, surface->y, surface->bpp, 
-               surface->clut.data ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY, 
-               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-       if (surface->clut.data)
+       png_write_info(png_ptr, info_ptr);
+       png_set_packing(png_ptr);
+
+       png_byte *row_pointer;
+       png_byte *cr = new png_byte[surface->y * surface->stride];
+       if (cr == NULL)
+       {
+               printf("Error: malloc\n");
+               return -5;
+       }
+       for (int i=0; i<surface->y; ++i)
        {
-               png_color palette[surface->clut.colors];
-               png_byte trans[surface->clut.colors];
-               for (int i=0; i<surface->clut.colors; ++i)
+               row_pointer=((png_byte*)surface->data)+i*surface->stride;
+               if (surface->bypp == 4)
                {
-                       palette[i].red=surface->clut.data[i].r;
-                       palette[i].green=surface->clut.data[i].g;
-                       palette[i].blue=surface->clut.data[i].b;
-                       trans[i]=255-surface->clut.data[i].a;
+                       memcpy(cr, row_pointer, surface->stride);
+                       for (int j=0; j<surface->stride; j+=4)
+                       {
+                               unsigned char tmp = cr[j];
+                               cr[j] = cr[j+2];
+                               cr[j+2]= tmp;
+                       }
+                       png_write_row(png_ptr, cr);
                }
-               png_set_PLTE(png_ptr, info_ptr, palette, surface->clut.colors);
-               png_set_tRNS(png_ptr, info_ptr, trans, surface->clut.colors, 0);
+               else
+                       png_write_row(png_ptr, row_pointer);
        }
-       png_write_info(png_ptr, info_ptr);
-       png_set_packing(png_ptr);
-       png_byte *row_pointers[surface->y];
-       for (int i=0; i<surface->y; ++i)
-               row_pointers[i]=((png_byte*)surface->data)+i*surface->stride;
-       png_write_image(png_ptr, row_pointers);
+       delete [] cr;
+
        png_write_end(png_ptr, info_ptr);
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);