added fastlz support in record device
[swftools.git] / lib / devices / render.c
index 19c0dbf..250356a 100644 (file)
@@ -25,9 +25,8 @@
 #include "../gfxdevice.h"
 #include "../gfxtools.h"
 #include "../mem.h"
-#define PNG_INLINE_EXPORTS
 #include "../types.h"
-#include "../png.c"
+#include "../png.h"
 #include "../log.h"
 #include "render.h"
 
@@ -48,6 +47,7 @@ typedef struct _renderline
 typedef struct _internal_result {
     gfximage_t img;
     struct _internal_result*next;
+    char palette;
 } internal_result_t;
 
 typedef struct _clipbuffer {
@@ -67,6 +67,8 @@ typedef struct _internal {
     int ymin, ymax;
     int fillwhite;
 
+    char palette;
+
     RGBA* img;
 
     clipbuffer_t*clipbuf;
@@ -86,7 +88,7 @@ typedef struct _fillinfo {
     gfxmatrix_t*matrix;
     gfxcxform_t*cxform;
     RGBA*gradient;
-    char clip_or_radial;
+    char linear_or_radial;
 } fillinfo_t;
 
 
@@ -272,16 +274,16 @@ static void fill_line_solid(RGBA*line, U32*z, int y, int x1, int x2, RGBA col)
 
     if(col.a!=255) {
         int ainv = 255-col.a;
-        col.r = (col.r*col.a)>>8;
-        col.g = (col.g*col.a)>>8;
-        col.b = (col.b*col.a)>>8;
+        col.r = (col.r*col.a)/255;
+        col.g = (col.g*col.a)/255;
+        col.b = (col.b*col.a)/255;
         do {
            if(z[bitpos]&bit) {
-               line[x].r = ((line[x].r*ainv)>>8)+col.r;
-               line[x].g = ((line[x].g*ainv)>>8)+col.g;
-               line[x].b = ((line[x].b*ainv)>>8)+col.b;
+               line[x].r = ((line[x].r*ainv)/255)+col.r;
+               line[x].g = ((line[x].g*ainv)/255)+col.g;
+               line[x].b = ((line[x].b*ainv)/255)+col.b;
                //line[x].a = 255;
-               line[x].a = ((line[x].a*ainv)>>8)+col.a;
+               line[x].a = ((line[x].a*ainv)/255)+col.a;
            }
            bit <<= 1;
            if(!bit) {
@@ -308,7 +310,7 @@ static void fill_line_bitmap(RGBA*line, U32*z, int y, int x1, int x2, fillinfo_t
     gfxmatrix_t*m = info->matrix;
     gfximage_t*b = info->image;
     
-    if(!b->width || !b->height) {
+    if(!b || !b->width || !b->height) {
        gfxcolor_t red = {255,255,0,0};
         fill_line_solid(line, z, y, x1, x2, red);
         return;
@@ -335,7 +337,7 @@ static void fill_line_bitmap(RGBA*line, U32*z, int y, int x1, int x2, fillinfo_t
            int yy = (int)(yy1 - x * yinc1);
            int ainv;
 
-           if(info->clip_or_radial) {
+           if(info->linear_or_radial) {
                if(xx<0) xx=0;
                if(xx>=b->width) xx = b->width-1;
                if(yy<0) yy=0;
@@ -351,9 +353,9 @@ static void fill_line_bitmap(RGBA*line, U32*z, int y, int x1, int x2, fillinfo_t
            ainv = 255-col.a;
 
            /* needs bitmap with premultiplied alpha */
-           line[x].r = ((line[x].r*ainv)>>8)+col.r;
-           line[x].g = ((line[x].g*ainv)>>8)+col.g;
-           line[x].b = ((line[x].b*ainv)>>8)+col.b;
+           line[x].r = ((line[x].r*ainv)/255)+col.r;
+           line[x].g = ((line[x].g*ainv)/255)+col.g;
+           line[x].b = ((line[x].b*ainv)/255)+col.b;
            line[x].a = 255;
        }
        bit <<= 1;
@@ -375,6 +377,7 @@ static void fill_line_gradient(RGBA*line, U32*z, int y, int x1, int x2, fillinfo
        /* x direction equals y direction */
        return;
     }
+    
     det = 1.0/det;
     double xx1 =  (  (-m->tx) * m->m11 - (y - m->ty) * m->m10) * det;
     double yy1 =  (- (-m->tx) * m->m01 + (y - m->ty) * m->m00) * det;
@@ -390,7 +393,7 @@ static void fill_line_gradient(RGBA*line, U32*z, int y, int x1, int x2, fillinfo
            int ainv;
 
             int pos = 0;
-            if(info->clip_or_radial) {
+            if(info->linear_or_radial) {
                 double xx = xx1 + x * xinc1;
                 double yy = yy1 + y * yinc1;
                 double r = sqrt(xx*xx + yy*yy);
@@ -406,9 +409,9 @@ static void fill_line_gradient(RGBA*line, U32*z, int y, int x1, int x2, fillinfo
            ainv = 255-col.a;
 
            /* needs bitmap with premultiplied alpha */
-           line[x].r = ((line[x].r*ainv)>>8)+col.r;
-           line[x].g = ((line[x].g*ainv)>>8)+col.g;
-           line[x].b = ((line[x].b*ainv)>>8)+col.b;
+           line[x].r = ((line[x].r*ainv)/255)+col.r;
+           line[x].g = ((line[x].g*ainv)/255)+col.g;
+           line[x].b = ((line[x].b*ainv)/255)+col.b;
            line[x].a = 255;
        }
        bit <<= 1;
@@ -517,6 +520,9 @@ int render_setparameter(struct _gfxdevice*dev, const char*key, const char*value)
     } else if(!strcmp(key, "fillwhite")) {
        i->fillwhite = atoi(value);
        return 1;
+    } else if(!strcmp(key, "palette")) {
+       i->palette = atoi(value);
+       return 1;
     }
     return 0;
 }
@@ -708,7 +714,7 @@ void render_fillgradient(struct _gfxdevice*dev, gfxline_t*line, gfxgradient_t*gr
     m2.m00 *= i->zoom; m2.m01 *= i->zoom; m2.tx *= i->zoom;
     m2.m10 *= i->zoom; m2.m11 *= i->zoom; m2.ty *= i->zoom;
 
-    info.clip_or_radial = type == gfxgradient_radial;
+    info.linear_or_radial = type == gfxgradient_radial;
 
     int pos = 0;
     gfxcolor_t color = {0,0,0,0};
@@ -793,12 +799,20 @@ int render_result_save(gfxresult_t*r, const char*filename)
        }
        while(i->next) {
            sprintf(filenamebuf, "%s.%d.png", origname, nr);
-           writePNG(filename, (unsigned char*)i->img.data, i->img.width, i->img.height);
+            if(!i->palette) {
+               writePNG(filename, (unsigned char*)i->img.data, i->img.width, i->img.height);
+            } else {
+               writePalettePNG(filename, (unsigned char*)i->img.data, i->img.width, i->img.height);
+            }
            nr++;
        }
        free(origname);
     } else {
-       writePNG(filename, (unsigned char*)i->img.data, i->img.width, i->img.height);
+        if(!i->palette) {
+           writePNG(filename, (unsigned char*)i->img.data, i->img.width, i->img.height);
+       } else {
+           writePalettePNG(filename, (unsigned char*)i->img.data, i->img.width, i->img.height);
+       }
     }
     return 1;
 }
@@ -807,7 +821,7 @@ char*gfximage_asXPM(gfximage_t*img, int depth)
     int d= 256/depth;
     char*str = (char*)malloc(img->width*img->height*4 + 500 + 16*depth*depth*depth);
     char*p = str;
-    p+= sprintf(p, "static char *noname[] = {\n\"%d %d 262144 3\",\n");
+    p+= sprintf(p, "static char *noname[] = {\n\"%d %d 262144 3\",\n", img->width, img->height);
     int r,g,b;
     for(r=0;r<depth;r++)
     for(g=0;g<depth;g++)
@@ -990,12 +1004,18 @@ void render_endpage(struct _gfxdevice*dev)
     }
 
     endclip(dev, 1);
+    int unclosed = 0;
     while(i->clipbuf) {
-       fprintf(stderr, "Warning: unclosed clip while processing endpage()\n");
        endclip(dev, 1);
+        unclosed++;
+    }
+
+    if(unclosed) {
+        fprintf(stderr, "Warning: %d unclosed clip(s) while processing endpage()\n", unclosed);
     }
     
     internal_result_t*ir= (internal_result_t*)rfx_calloc(sizeof(internal_result_t));
+    ir->palette = i->palette;
 
     int y,x;
 
@@ -1058,3 +1078,10 @@ void gfxdevice_render_init(gfxdevice_t*dev)
     dev->finish = render_finish;
 }
 
+
+gfxdevice_t* gfxdevice_render_new()
+{
+    gfxdevice_t* d = (gfxdevice_t*)malloc(sizeof(gfxdevice_t));
+    gfxdevice_render_init(d);
+    return d;
+}