+ return ok;
+}
+
+typedef unsigned char byte;
+#define ABS(a) ((a)>0?(a):(-(a)))
+byte inline PaethPredictor (byte a,byte b,byte c)
+{
+ // a = left, b = above, c = upper left
+ int p = a + b - c; // initial estimate
+ int pa = ABS(p - a); // distances to a, b, c
+ int pb = ABS(p - b);
+ int pc = ABS(p - c);
+ // return nearest of a,b,c,
+ // breaking ties in order a,b,c.
+ if (pa <= pb && pa <= pc)
+ return a;
+ else if (pb <= pc)
+ return b;
+ else return c;
+}
+
+void applyfilter3(int mode, U8*src, U8*old, U8*dest, int width)
+{
+ int x;
+ unsigned char lastr=0;
+ unsigned char lastg=0;
+ unsigned char lastb=0;
+ unsigned char upperlastr=0;
+ unsigned char upperlastg=0;
+ unsigned char upperlastb=0;
+
+ if(mode==0) {
+ for(x=0;x<width;x++) {
+ dest[0] = 255;
+ dest[1] = src[0];
+ dest[2] = src[1];
+ dest[3] = src[2];
+ dest+=4;
+ src+=3;
+ }
+ }
+ else if(mode==1) {
+ for(x=0;x<width;x++) {
+ dest[0] = 255;
+ dest[1] = src[0]+lastr;
+ dest[2] = src[1]+lastg;
+ dest[3] = src[2]+lastb;
+ lastr = dest[1];
+ lastg = dest[2];
+ lastb = dest[3];
+ dest+=4;
+ src+=3;
+ }
+ }
+ else if(mode==2) {
+ for(x=0;x<width;x++) {
+ dest[0] = 255;
+ dest[1] = src[0]+old[1];
+ dest[2] = src[1]+old[2];
+ dest[3] = src[2]+old[3];
+ dest+=4;
+ old+=4;
+ src+=3;
+ }
+ }
+ else if(mode==3) {
+ for(x=0;x<width;x++) {
+ dest[0] = 255;
+ dest[1] = src[0]+(old[1]+lastr)/2;
+ dest[2] = src[1]+(old[2]+lastg)/2;
+ dest[3] = src[2]+(old[3]+lastb)/2;
+ lastr = dest[1];
+ lastg = dest[2];
+ lastb = dest[3];
+ dest+=4;
+ old+=4;
+ src+=3;
+ }
+ }
+ else if(mode==4) {
+ for(x=0;x<width;x++) {
+ dest[0] = 255;
+ dest[1] = src[0]+PaethPredictor(lastr,old[1],upperlastr);
+ dest[2] = src[1]+PaethPredictor(lastg,old[2],upperlastg);
+ dest[3] = src[2]+PaethPredictor(lastb,old[3],upperlastb);
+ lastr = dest[1];
+ lastg = dest[2];
+ lastb = dest[3];
+ upperlastr = old[1];
+ upperlastg = old[2];
+ upperlastb = old[3];
+ dest+=4;
+ old+=4;
+ src+=3;
+ }
+ }
+
+}
+
+void applyfilter4(int mode, U8*src, U8*old, U8*dest, int width)
+{
+ int x;
+ unsigned char lastr=0;
+ unsigned char lastg=0;
+ unsigned char lastb=0;
+ unsigned char lasta=0;
+ unsigned char upperlastr=0;
+ unsigned char upperlastg=0;
+ unsigned char upperlastb=0;
+ unsigned char upperlasta=0;
+
+ if(mode==0) {
+ for(x=0;x<width;x++) {
+ dest[0] = src[3];
+ dest[1] = src[0];
+ dest[2] = src[1];
+ dest[3] = src[2];
+ dest+=4;
+ src+=4;
+ }
+ }
+ else if(mode==1) {
+ for(x=0;x<width;x++) {
+ dest[0] = src[3]+lasta;
+ dest[1] = src[0]+lastr;
+ dest[2] = src[1]+lastg;
+ dest[3] = src[2]+lastb;
+ lasta = dest[0];
+ lastr = dest[1];
+ lastg = dest[2];
+ lastb = dest[3];
+ dest+=4;
+ src+=4;
+ }
+ }
+ else if(mode==2) {
+ for(x=0;x<width;x++) {
+ dest[0] = src[3]+old[0];
+ dest[1] = src[0]+old[1];
+ dest[2] = src[1]+old[2];
+ dest[3] = src[2]+old[3];
+ dest+=4;
+ old+=4;
+ src+=4;
+ }
+ }
+ else if(mode==3) {
+ for(x=0;x<width;x++) {
+ dest[0] = src[3]+(old[0]+lasta)/2;
+ dest[1] = src[0]+(old[1]+lastr)/2;
+ dest[2] = src[1]+(old[2]+lastg)/2;
+ dest[3] = src[2]+(old[3]+lastb)/2;
+ lastr = dest[1];
+ lastg = dest[2];
+ lastb = dest[3];
+ dest+=4;
+ old+=4;
+ src+=4;
+ }
+ }
+ else if(mode==4) {
+ for(x=0;x<width;x++) {
+ dest[0] = src[3]+PaethPredictor(lasta,old[0],upperlasta);
+ dest[1] = src[0]+PaethPredictor(lastr,old[1],upperlastr);
+ dest[2] = src[1]+PaethPredictor(lastg,old[2],upperlastg);
+ dest[3] = src[2]+PaethPredictor(lastb,old[3],upperlastb);
+ lasta = dest[0];
+ lastr = dest[1];
+ lastg = dest[2];
+ lastb = dest[3];
+ upperlasta = old[0];
+ upperlastr = old[1];
+ upperlastg = old[2];
+ upperlastb = old[3];
+ dest+=4;
+ old+=4;
+ src+=4;
+ }
+ }
+
+}
+
+void applyfilter1(int mode, U8*src, U8*old, U8*dest, int width)
+{
+ int x;
+ unsigned char last=0;
+ unsigned char upperlast=0;
+
+ if(mode==0) {
+ for(x=0;x<width;x++) {
+ *dest = *src;
+ dest++;
+ src++;
+ }
+ }
+ else if(mode==1) {
+ for(x=0;x<width;x++) {
+ *dest = *src+last;
+ last = *dest;
+ dest++;
+ src++;
+ }
+ }
+ else if(mode==2) {
+ for(x=0;x<width;x++) {
+ *dest = *src+*old;
+ dest++;
+ old++;
+ src++;
+ }
+ }
+ else if(mode==3) {
+ for(x=0;x<width;x++) {
+ *dest = *src+(*old+last)/2;
+ dest++;
+ old++;
+ src++;
+ }
+ }
+ else if(mode==4) {
+ for(x=0;x<width;x++) {
+ *dest = *src+PaethPredictor(last,*old,upperlast);
+ last = *dest;
+ upperlast = *old;
+ dest++;
+ old++;
+ src++;
+ }
+ }
+