Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / usb / media / pwc / pwc-dec23.c
1 /* Linux driver for Philips webcam
2    Decompression for chipset version 2 et 3
3    (C) 2004      Luc Saillard (luc@saillard.org)
4
5    NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
6    driver and thus may have bugs that are not present in the original version.
7    Please send bug reports and support requests to <luc@saillard.org>.
8    The decompression routines have been implemented by reverse-engineering the
9    Nemosoft binary pwcx module. Caveat emptor.
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 */
25
26 #include "pwc-timon.h"
27 #include "pwc-kiara.h"
28 #include "pwc-dec23.h"
29 #include "pwc-ioctl.h"
30
31 #include <linux/string.h>
32
33 /****
34  *
35  *
36  *
37  */
38
39
40 static void fill_table_a000(unsigned int *p)
41 {
42   static unsigned int initial_values[12] = {
43      0xFFAD9B00, 0xFFDDEE00, 0x00221200, 0x00526500,
44      0xFFC21E00, 0x003DE200, 0xFF924B80, 0xFFD2A300,
45      0x002D5D00, 0x006DB480, 0xFFED3E00, 0x0012C200
46   };
47   static unsigned int values_derivated[12] = {
48      0x0000A4CA, 0x00004424, 0xFFFFBBDC, 0xFFFF5B36,
49      0x00007BC4, 0xFFFF843C, 0x0000DB69, 0x00005ABA,
50      0xFFFFA546, 0xFFFF2497, 0x00002584, 0xFFFFDA7C
51   };
52   unsigned int temp_values[12];
53   int i,j;
54
55   memcpy(temp_values,initial_values,sizeof(initial_values));
56   for (i=0;i<256;i++)
57    {
58      for (j=0;j<12;j++)
59       {
60         *p++ = temp_values[j];
61         temp_values[j] += values_derivated[j];
62       }
63    }
64 }
65
66 static void fill_table_d000(unsigned char *p)
67 {
68   int bit,byte;
69
70   for (bit=0; bit<8; bit++)
71    {
72      unsigned char bitpower = 1<<bit;
73      unsigned char mask = bitpower-1;
74      for (byte=0; byte<256; byte++)
75       {
76         if (byte & bitpower)
77           *p++ = -(byte & mask);
78         else
79           *p++ = (byte & mask);
80       }
81    }
82 }
83
84 /*
85  *
86  * Kiara: 0 <= ver <= 7
87  * Timon: 0 <= ver <= 15
88  *
89  */
90 static void fill_table_color(unsigned int version, const unsigned int *romtable, 
91     unsigned char *p0004, 
92     unsigned char *p8004)
93 {
94   const unsigned int *table;
95   unsigned char *p0, *p8;
96   int i,j,k;
97   int dl,bit,pw;
98
99   romtable += version*256;
100
101   for (i=0; i<2; i++)
102    {
103      table = romtable + i*128;
104
105      for (dl=0; dl<16; dl++)
106       {
107         p0 = p0004 + (i<<14) + (dl<<10);
108         p8 = p8004 + (i<<12) + (dl<<8);
109
110         for (j=0; j<8; j++ , table++, p0+=128)
111          {
112            for (k=0; k<16; k++)
113             {
114               if (k==0)
115                 bit=1;
116               else if (k>=1 && k<3)
117                 bit=(table[0]>>15)&7;
118               else if (k>=3 && k<6)
119                 bit=(table[0]>>12)&7;
120               else if (k>=6 && k<10)
121                 bit=(table[0]>>9)&7;
122               else if (k>=10 && k<13)
123                 bit=(table[0]>>6)&7;
124               else if (k>=13 && k<15)
125                 bit=(table[0]>>3)&7;
126               else
127                 bit=(table[0])&7;
128               if (k == 0)
129                 *(unsigned char *)p8++ = 8;
130               else
131                 *(unsigned char *)p8++ = j - bit;
132               *(unsigned char *)p8++ = bit;
133
134               pw = 1<<bit;
135               p0[k+0x00] = (1*pw)  + 0x80;
136               p0[k+0x10] = (2*pw)  + 0x80;
137               p0[k+0x20] = (3*pw)  + 0x80;
138               p0[k+0x30] = (4*pw)  + 0x80;
139               p0[k+0x40] = (-pw)   + 0x80;
140               p0[k+0x50] = (2*-pw) + 0x80;
141               p0[k+0x60] = (3*-pw) + 0x80;
142               p0[k+0x70] = (4*-pw) + 0x80;
143             } /* end of for (k=0; k<16; k++, p8++) */
144          } /* end of for (j=0; j<8; j++ , table++) */
145       } /* end of for (dl=0; dl<16; dl++) */
146    } /* end of for (i=0; i<2; i++) */
147 }
148
149 /*
150  * precision = (pdev->xx + pdev->yy)
151  *
152  */
153 static void fill_table_dc00_d800(unsigned int precision, unsigned int *pdc00, unsigned int *pd800)
154 {
155   int i;
156   unsigned int offset1, offset2;
157  
158   for(i=0,offset1=0x4000, offset2=0; i<256 ; i++,offset1+=0x7BC4, offset2+=0x7BC4)
159    {
160      unsigned int msb = offset1 >> 15;
161
162      if ( msb > 255)
163       {
164         if (msb)
165           msb=0;
166         else
167           msb=255;
168       }
169
170      *pdc00++ = msb << precision;
171      *pd800++ = offset2;
172    }
173
174 }
175
176 /*
177  * struct {
178  *   unsigned char op;      // operation to execute
179  *   unsigned char bits;    // bits use to perform operation
180  *   unsigned char offset1; // offset to add to access in the table_0004 % 16
181  *   unsigned char offset2; // offset to add to access in the table_0004
182  * }
183  *
184  */
185 static unsigned int table_ops[] = {
186 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x30,
187 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
188 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
189 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
190 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x10,
191 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
192 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
193 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00,
194 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x70,
195 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00,
196 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00,
197 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00,
198 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x50,
199 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00,
200 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40,
201 0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00
202 };
203
204 /*
205  * TODO: multiply by 4 all values
206  *
207  */
208 static unsigned int MulIdx[256] = {
209  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210  0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
211  0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
212  4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,
213  6, 7, 8, 9, 7,10,11, 8, 8,11,10, 7, 9, 8, 7, 6,
214  4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,
215  1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,
216  0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,
217  0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,
218  1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,
219  7,10,11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8,11,10, 7,
220  4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,
221  7, 9, 6, 8,10, 8, 7,11,11, 7, 8,10, 8, 6, 9, 7,
222  1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,
223  1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,
224 10, 8, 7,11, 8, 6, 9, 7, 7, 9, 6, 8,11, 7, 8,10
225 };
226
227
228
229 void pwc_dec23_init(int type, int release, unsigned char *mode, void *data)
230 {
231   int flags;
232   struct pwc_dec23_private *pdev = data;
233   release = release;
234
235   switch (type)
236    {
237     case 720:
238     case 730:
239     case 740:
240     case 750:
241       flags = mode[2]&0x18;     /* our: flags = 8, mode[2]==e8 */
242       if (flags==8)
243         pdev->zz = 7;
244       else if (flags==0x10)
245         pdev->zz = 8;
246       else
247         pdev->zz = 6;
248       flags = mode[2]>>5;       /* our: 7 */
249
250       fill_table_color(flags, (unsigned int *)KiaraRomTable, pdev->table_0004, pdev->table_8004);
251       break;
252
253
254     case 675:
255     case 680:
256     case 690:
257       flags = mode[2]&6;
258       if (flags==2)
259         pdev->zz = 7;
260       else if (flags==4)
261         pdev->zz = 8;
262       else
263         pdev->zz = 6;
264       flags = mode[2]>>3;
265
266       fill_table_color(flags, (unsigned int *)TimonRomTable, pdev->table_0004, pdev->table_8004);
267       break;
268
269     default:
270       /* Not supported */
271       return;
272    }
273
274   /* * * * ** */
275   pdev->xx = 8 - pdev->zz;
276   pdev->yy = 15 - pdev->xx;
277   pdev->zzmask = 0xFF>>pdev->xx;
278   //pdev->zzmask = (1U<<pdev->zz)-1;
279
280
281   fill_table_dc00_d800(pdev->xx + pdev->yy, pdev->table_dc00, pdev->table_d800);
282   fill_table_a000(pdev->table_a004);
283   fill_table_d000(pdev->table_d004);
284 }
285
286
287 /*
288  * To manage the stream, we keep in a 32 bits variables,
289  * the next bits in the stream. fill_reservoir() add to
290  * the reservoir at least wanted nbits.
291  *
292  *
293  */
294 #define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
295    while (nbits_in_reservoir<nbits_wanted) \
296     { \
297       reservoir |= (*(stream)++) << nbits_in_reservoir; \
298       nbits_in_reservoir+=8; \
299     } \
300 }  while(0);
301
302 #define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
303    fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted); \
304    result = (reservoir) & ((1U<<nbits_wanted)-1); \
305    reservoir >>= nbits_wanted; \
306    nbits_in_reservoir -= nbits_wanted; \
307 }  while(0);
308
309
310
311 static void DecompressBand23(const struct pwc_dec23_private *pdev,
312                              const unsigned char *rawyuv,
313                              unsigned char *planar_y,
314                              unsigned char *planar_u,
315                              unsigned char *planar_v,
316                              unsigned int image_x,              /* aka number of pixels wanted ??? */
317                              unsigned int pixels_per_line,      /* aka number of pixels per line */
318                              int flags)
319 {
320
321
322   unsigned int reservoir, nbits_in_reservoir;
323   int first_4_bits;
324   unsigned int bytes_per_channel;
325   int line_size;        /* size of the line (4Y+U+V) */
326   int passes;
327   const unsigned char *ptable0004, *ptable8004;
328
329   int even_line;
330   unsigned int temp_colors[16];
331   int nblocks;
332
333   const unsigned char *stream;
334   unsigned char *dest_y, *dest_u=NULL, *dest_v=NULL;
335   unsigned int offset_to_plane_u, offset_to_plane_v;
336
337   int i;
338
339
340   reservoir = 0;
341   nbits_in_reservoir = 0;
342   stream = rawyuv+1;    /* The first byte of the stream is skipped */
343   even_line = 1;
344
345   get_nbits(reservoir,nbits_in_reservoir,stream,4,first_4_bits);
346
347   line_size = pixels_per_line*3;
348
349   for (passes=0;passes<2;passes++)
350    {
351      if (passes==0)
352       {
353         bytes_per_channel = pixels_per_line;
354         dest_y = planar_y;
355         nblocks = image_x/4;
356       }
357      else
358       {
359         /* Format planar: All Y, then all U, then all V */
360         bytes_per_channel = pixels_per_line/2;
361         dest_u = planar_u;
362         dest_v = planar_v;
363         dest_y = dest_u;
364         nblocks = image_x/8;
365       }
366
367      offset_to_plane_u = bytes_per_channel*2;
368      offset_to_plane_v = bytes_per_channel*3;
369      /*
370      printf("bytes_per_channel = %d\n",bytes_per_channel);
371      printf("offset_to_plane_u = %d\n",offset_to_plane_u);
372      printf("offset_to_plane_v = %d\n",offset_to_plane_v);
373      */
374
375      while (nblocks-->0)
376       {
377         unsigned int gray_index;
378
379         fill_nbits(reservoir,nbits_in_reservoir,stream,16);
380         gray_index = reservoir & pdev->zzmask;
381         reservoir >>= pdev->zz;
382         nbits_in_reservoir -= pdev->zz;
383
384         fill_nbits(reservoir,nbits_in_reservoir,stream,2);
385
386         if ( (reservoir & 3) == 0)
387          {
388            reservoir>>=2;
389            nbits_in_reservoir-=2;
390            for (i=0;i<16;i++)
391              temp_colors[i] = pdev->table_dc00[gray_index];
392
393          }
394         else
395          {
396            unsigned int channel_v, offset1;
397
398            /* swap bit 0 and 2 of offset_OR */
399            channel_v = ((reservoir & 1) << 2) | (reservoir & 2) | ((reservoir & 4)>>2);
400            reservoir>>=3;
401            nbits_in_reservoir-=3;
402
403            for (i=0;i<16;i++)
404              temp_colors[i] = pdev->table_d800[gray_index];
405
406            ptable0004 = pdev->table_0004 + (passes*16384) + (first_4_bits*1024) + (channel_v*128);
407            ptable8004 = pdev->table_8004 + (passes*4096)  + (first_4_bits*256)  + (channel_v*32);
408
409            offset1 = 0;
410            while(1) 
411             {
412               unsigned int index_in_table_ops, op, rows=0;
413               fill_nbits(reservoir,nbits_in_reservoir,stream,16);
414
415               /* mode is 0,1 or 2 */
416               index_in_table_ops = (reservoir&0x3F);
417               op = table_ops[ index_in_table_ops*4 ];
418               if (op == 2)
419                {
420                  reservoir >>= 2;
421                  nbits_in_reservoir -= 2;
422                  break; /* exit the while(1) */
423                }
424               if (op == 0)
425                {
426                  unsigned int shift;
427
428                  offset1 = (offset1 + table_ops[index_in_table_ops*4+2]) & 0x0F;
429                  shift = table_ops[ index_in_table_ops*4+1 ];
430                  reservoir >>= shift;
431                  nbits_in_reservoir -= shift;
432                  rows = ptable0004[ offset1 + table_ops[index_in_table_ops*4+3] ];
433                }
434               if (op == 1)
435                {
436                   /* 10bits [ xxxx xxxx yyyy 000 ]
437                    * yyy => offset in the table8004
438                    * xxx => offset in the tabled004
439                    */
440                  unsigned int mask, shift;
441                  unsigned int col1, row1, total_bits;
442
443                  offset1 = (offset1 + ((reservoir>>3)&0x0F)+1) & 0x0F;
444
445                  col1 = (reservoir>>7) & 0xFF;
446                  row1 = ptable8004 [ offset1*2 ];
447
448                  /* Bit mask table */
449                  mask = pdev->table_d004[ (row1<<8) + col1 ];
450                  shift = ptable8004 [ offset1*2 + 1];
451                  rows = ((mask << shift) + 0x80) & 0xFF;
452
453                  total_bits = row1 + 8;
454                  reservoir >>= total_bits;
455                  nbits_in_reservoir -= total_bits;
456                }
457                {
458                  const unsigned int *table_a004 = pdev->table_a004 + rows*12;
459                  unsigned int *poffset = MulIdx + offset1*16;   /* 64/4 (int) */
460                  for (i=0;i<16;i++)
461                   {
462                     temp_colors[i] += table_a004[ *poffset ];
463                     poffset++;
464                   }
465                }
466            }
467          }
468 #define USE_SIGNED_INT_FOR_COLOR
469 #ifdef USE_SIGNED_INT_FOR_COLOR
470 #  define CLAMP(x) ((x)>255?255:((x)<0?0:x))
471 #else
472 #  define CLAMP(x) ((x)>255?255:x)
473 #endif
474
475         if (passes == 0)
476          {
477 #ifdef USE_SIGNED_INT_FOR_COLOR
478            const int *c = temp_colors;
479 #else
480            const unsigned int *c = temp_colors;
481 #endif
482            unsigned char *d;
483
484            d = dest_y;
485            for (i=0;i<4;i++,c++)
486              *d++ = CLAMP((*c) >> pdev->yy);
487
488            d = dest_y + bytes_per_channel;
489            for (i=0;i<4;i++,c++)
490              *d++ = CLAMP((*c) >> pdev->yy);
491
492            d = dest_y + offset_to_plane_u;
493            for (i=0;i<4;i++,c++)
494              *d++ = CLAMP((*c) >> pdev->yy);
495
496            d = dest_y + offset_to_plane_v;
497            for (i=0;i<4;i++,c++)
498              *d++ = CLAMP((*c) >> pdev->yy);
499
500            dest_y += 4;
501          }
502         else if (passes == 1)
503          {
504 #ifdef USE_SIGNED_INT_FOR_COLOR
505            int *c1 = temp_colors;
506            int *c2 = temp_colors+4;
507 #else
508            unsigned int *c1 = temp_colors;
509            unsigned int *c2 = temp_colors+4;
510 #endif
511            unsigned char *d;
512
513            d = dest_y;
514            for (i=0;i<4;i++,c1++,c2++)
515             {
516               *d++ = CLAMP((*c1) >> pdev->yy);
517               *d++ = CLAMP((*c2) >> pdev->yy);
518             }
519            c1 = temp_colors+12;
520            //c2 = temp_colors+8;
521            d = dest_y + bytes_per_channel;
522            for (i=0;i<4;i++,c1++,c2++)
523             {
524               *d++ = CLAMP((*c1) >> pdev->yy);
525               *d++ = CLAMP((*c2) >> pdev->yy);
526             }
527
528            if (even_line)       /* Each line, swap u/v */
529             {
530               even_line=0;
531               dest_y = dest_v;
532               dest_u += 8;
533             }
534            else
535             {
536               even_line=1;
537               dest_y = dest_u;
538               dest_v += 8;
539             }
540          }
541
542       } /* end of while (nblocks-->0) */
543
544    } /* end of for (passes=0;passes<2;passes++) */
545
546 }
547
548
549 /**
550  *
551  * image: size of the image wanted
552  * view : size of the image returned by the camera
553  * offset: (x,y) to displayer image in the view
554  *
555  * src: raw data
556  * dst: image output
557  * flags: PWCX_FLAG_PLANAR
558  * pdev: private buffer
559  * bandlength:
560  *
561  */
562 void pwc_dec23_decompress(const struct pwc_coord *image,
563                             const struct pwc_coord *view,
564                             const struct pwc_coord *offset,
565                             const void *src,
566                             void *dst,
567                             int flags,
568                             const void *data,
569                             int bandlength)
570 {
571   const struct pwc_dec23_private *pdev = data;
572   unsigned char *pout, *pout_planar_y=NULL, *pout_planar_u=NULL, *pout_planar_v=NULL;
573   int i,n,stride,pixel_size;
574
575
576   if (flags & PWCX_FLAG_BAYER)
577    {
578      pout = dst + (view->x * offset->y) + offset->x;
579      pixel_size = view->x * 4;
580    }
581   else
582    {
583      n = view->x * view->y;
584
585      /* offset in Y plane */
586      stride = view->x * offset->y;
587      pout_planar_y = dst + stride + offset->x;
588
589      /* offsets in U/V planes */
590      stride = (view->x * offset->y)/4 + offset->x/2;
591      pout_planar_u = dst + n +     + stride;
592      pout_planar_v = dst + n + n/4 + stride;
593
594      pixel_size = view->x * 4;
595    }
596
597
598   for (i=0;i<image->y;i+=4)
599    {
600      if (flags & PWCX_FLAG_BAYER)
601       {
602         //TODO:
603         //DecompressBandBayer(pdev,src,pout,image.x,view->x,flags);
604         src += bandlength;
605         pout += pixel_size;
606       }
607      else
608       {
609         DecompressBand23(pdev,src,pout_planar_y,pout_planar_u,pout_planar_v,image->x,view->x,flags);
610         src += bandlength;
611         pout_planar_y += pixel_size;
612         pout_planar_u += view->x;
613         pout_planar_v += view->x;
614       }
615    }
616 }
617
618 void pwc_dec23_exit(void)
619 {
620   /* Do nothing */
621
622 }
623