viewer.c: A first working version with 16bpp.
[libopano.git] / src / viewer.c
index 55cc106..123d42b 100644 (file)
@@ -25,6 +25,7 @@
 #include <X11/Xatom.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include "filter.h"
 
 void   PV_ExtractStill( TrformStr *TrPtr );
@@ -36,6 +37,8 @@ int   SetUpMweights();
 void   DrawWindow();
 void   DrawView(int InterPolator);
 
+int readJPEG ( Image *im, fullPath *sfile );
+
 int                                    panning = FALSE;
 int                                    zooming_in = FALSE;
 int                                    zooming_out = FALSE;
@@ -59,7 +62,6 @@ int                   oldposx, oldposy;
 
 int main( int argc, char** argv )
 {
-       KeySym key;
        XSizeHints hint;
        unsigned long fg, bg;
        int done;
@@ -90,7 +92,6 @@ int main( int argc, char** argv )
        if( depth != 24 )
        {
                PrintError("Depth = %d, must be 24 pixels", (int)depth);
-               exit(0);
        }
        bg = WhitePixel(disp,screen);
        fg = BlackPixel(disp,screen);
@@ -338,6 +339,8 @@ _EventLoop:
        XFreeGC(disp,gc);
        XDestroyWindow(disp, win);
        XCloseDisplay(disp);
+
+       return (0);
 }
        
 
@@ -452,7 +455,97 @@ void ThreeToFourBPP( Image *im )
        im->dataSize = im->height * im->bytesPerLine;
 }
 
+static int copy_rgb_to_zpixmap (XImage *dest, const Image *src)
+{
+       uint32_t *src_data;
+
+       uint32_t src_r;
+       uint32_t src_g;
+       uint32_t src_b;
+
+       uint32_t dest_r;
+       uint32_t dest_g;
+       uint32_t dest_b;
+       uint32_t dest_pixel_value;
+
+       uint32_t x;
+       uint32_t y;
+       uint32_t pixel;
+
+       uint32_t dest_r_maxval;
+       uint32_t dest_g_maxval;
+       uint32_t dest_b_maxval;
+
+       uint32_t dest_r_offset;
+       uint32_t dest_g_offset;
+       uint32_t dest_b_offset;
+
+       dest_r_offset = 0;
+       dest_g_offset = 0;
+       dest_b_offset = 0;
+       dest_r_maxval = dest->red_mask;
+       dest_g_maxval = dest->green_mask;
+       dest_b_maxval = dest->blue_mask;
+       for (x = 0; x < dest->depth; x++)
+       {
+               if ((dest_r_maxval & 0x01) == 0)
+               {
+                       dest_r_offset++;
+                       dest_r_maxval >>= 1;
+               }
+               if ((dest_g_maxval & 0x01) == 0)
+               {
+                       dest_g_offset++;
+                       dest_g_maxval >>= 1;
+               }
+               if ((dest_b_maxval & 0x01) == 0)
+               {
+                       dest_b_offset++;
+                       dest_b_maxval >>= 1;
+               }
+       }
 
+       src_data = (uint32_t *) *src->data;
+
+       pixel = 0;
+       for (y = 0; y < dest->height; y++)
+       {
+               for (x = 0; x < dest->width; x++, pixel++)
+               {
+                       int32_t bytenum;
+
+                       src_r = (src_data[pixel] >>  8) & 0xFF;
+                       src_g = (src_data[pixel] >> 16) & 0xFF;
+                       src_b = (src_data[pixel] >> 24) & 0xFF;
+
+                       dest_r = dest_r_maxval * src_r / 0xFF;
+                       dest_g = dest_g_maxval * src_g / 0xFF;
+                       dest_b = dest_b_maxval * src_b / 0xFF;
+
+                       dest_pixel_value = 0
+                               | ((dest_r << dest_r_offset) & dest->red_mask)
+                               | ((dest_g << dest_g_offset) & dest->green_mask)
+                               | ((dest_b << dest_b_offset) & dest->blue_mask);
+
+                       if ((y == 150) && (x == 200))
+                               printf ("[200x150] RGB(%u,%u,%u) -> RGB(%u,%u,%u) -> 0x%04x\n",
+                                               src_r, src_g, src_b,
+                                               dest_r, dest_g, dest_b,
+                                               dest_pixel_value);
+                       for (bytenum = 0; bytenum < (dest->depth / 8); bytenum++)
+                       {
+                               int offset = (pixel * dest->bits_per_pixel / 8) + bytenum;
+                               dest->data[(pixel * dest->bits_per_pixel / 8) + bytenum] = 
+                                       (dest_pixel_value >> (dest->bits_per_pixel - (8 * (bytenum + 1)))) & 0xFF;
+                               if ((y == 150) && (x == 200))
+                                       printf ("Setting byte #%i to 0x%02x\n",
+                                                       offset, dest->data[offset]);
+                       }
+               }
+       }
+
+       return (0);
+} /* int copy_rgb_to_zpixmap */
 
 void DrawWindow()
 {
@@ -488,8 +581,18 @@ void DrawWindow()
                else
                        DrawView(_bilinear);
        }
-                       
+
+       ximage->data = (char *) malloc (view.dataSize);
+       if (ximage->data == NULL)
+               return;
+       memcpy (ximage->data, *(view.data), view.dataSize);
+
+       copy_rgb_to_zpixmap (ximage, &view);
+
        XPutImage(disp, win, gc, ximage, 0, 0, 0, 0, view.width, view.height);
+
+       free (ximage->data);
+       ximage->data = NULL;
 }
 
 void DrawView(int InterPolator)