[PATCH] aic7xxx_osm build fix
[cris-mirror.git] / drivers / usb / media / pwc / pwc-dec23.c
blob98fa3f7a9eff4721531ca060cee5961f7fba0100
1 /* Linux driver for Philips webcam
2 Decompression for chipset version 2 et 3
3 (C) 2004 Luc Saillard (luc@saillard.org)
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.
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.
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.
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
26 #include "pwc-timon.h"
27 #include "pwc-kiara.h"
28 #include "pwc-dec23.h"
29 #include "pwc-ioctl.h"
31 #include <linux/string.h>
33 /****
40 static void fill_table_a000(unsigned int *p)
42 static unsigned int initial_values[12] = {
43 0xFFAD9B00, 0xFFDDEE00, 0x00221200, 0x00526500,
44 0xFFC21E00, 0x003DE200, 0xFF924B80, 0xFFD2A300,
45 0x002D5D00, 0x006DB480, 0xFFED3E00, 0x0012C200
47 static unsigned int values_derivated[12] = {
48 0x0000A4CA, 0x00004424, 0xFFFFBBDC, 0xFFFF5B36,
49 0x00007BC4, 0xFFFF843C, 0x0000DB69, 0x00005ABA,
50 0xFFFFA546, 0xFFFF2497, 0x00002584, 0xFFFFDA7C
52 unsigned int temp_values[12];
53 int i,j;
55 memcpy(temp_values,initial_values,sizeof(initial_values));
56 for (i=0;i<256;i++)
58 for (j=0;j<12;j++)
60 *p++ = temp_values[j];
61 temp_values[j] += values_derivated[j];
66 static void fill_table_d000(unsigned char *p)
68 int bit,byte;
70 for (bit=0; bit<8; bit++)
72 unsigned char bitpower = 1<<bit;
73 unsigned char mask = bitpower-1;
74 for (byte=0; byte<256; byte++)
76 if (byte & bitpower)
77 *p++ = -(byte & mask);
78 else
79 *p++ = (byte & mask);
86 * Kiara: 0 <= ver <= 7
87 * Timon: 0 <= ver <= 15
90 static void fill_table_color(unsigned int version, const unsigned int *romtable,
91 unsigned char *p0004,
92 unsigned char *p8004)
94 const unsigned int *table;
95 unsigned char *p0, *p8;
96 int i,j,k;
97 int dl,bit,pw;
99 romtable += version*256;
101 for (i=0; i<2; i++)
103 table = romtable + i*128;
105 for (dl=0; dl<16; dl++)
107 p0 = p0004 + (i<<14) + (dl<<10);
108 p8 = p8004 + (i<<12) + (dl<<8);
110 for (j=0; j<8; j++ , table++, p0+=128)
112 for (k=0; k<16; k++)
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;
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++) */
150 * precision = (pdev->xx + pdev->yy)
153 static void fill_table_dc00_d800(unsigned int precision, unsigned int *pdc00, unsigned int *pd800)
155 int i;
156 unsigned int offset1, offset2;
158 for(i=0,offset1=0x4000, offset2=0; i<256 ; i++,offset1+=0x7BC4, offset2+=0x7BC4)
160 unsigned int msb = offset1 >> 15;
162 if ( msb > 255)
164 if (msb)
165 msb=0;
166 else
167 msb=255;
170 *pdc00++ = msb << precision;
171 *pd800++ = offset2;
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
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
205 * TODO: multiply by 4 all values
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
229 void pwc_dec23_init(int type, int release, unsigned char *mode, void *data)
231 int flags;
232 struct pwc_dec23_private *pdev = data;
233 release = release;
235 switch (type)
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 */
250 fill_table_color(flags, (unsigned int *)KiaraRomTable, pdev->table_0004, pdev->table_8004);
251 break;
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;
266 fill_table_color(flags, (unsigned int *)TimonRomTable, pdev->table_0004, pdev->table_8004);
267 break;
269 default:
270 /* Not supported */
271 return;
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;
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);
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.
294 #define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
295 while (nbits_in_reservoir<nbits_wanted) \
297 reservoir |= (*(stream)++) << nbits_in_reservoir; \
298 nbits_in_reservoir+=8; \
300 } while(0);
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);
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)
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;
329 int even_line;
330 unsigned int temp_colors[16];
331 int nblocks;
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;
337 int i;
340 reservoir = 0;
341 nbits_in_reservoir = 0;
342 stream = rawyuv+1; /* The first byte of the stream is skipped */
343 even_line = 1;
345 get_nbits(reservoir,nbits_in_reservoir,stream,4,first_4_bits);
347 line_size = pixels_per_line*3;
349 for (passes=0;passes<2;passes++)
351 if (passes==0)
353 bytes_per_channel = pixels_per_line;
354 dest_y = planar_y;
355 nblocks = image_x/4;
357 else
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;
367 offset_to_plane_u = bytes_per_channel*2;
368 offset_to_plane_v = bytes_per_channel*3;
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);
375 while (nblocks-->0)
377 unsigned int gray_index;
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;
384 fill_nbits(reservoir,nbits_in_reservoir,stream,2);
386 if ( (reservoir & 3) == 0)
388 reservoir>>=2;
389 nbits_in_reservoir-=2;
390 for (i=0;i<16;i++)
391 temp_colors[i] = pdev->table_dc00[gray_index];
394 else
396 unsigned int channel_v, offset1;
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;
403 for (i=0;i<16;i++)
404 temp_colors[i] = pdev->table_d800[gray_index];
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);
409 offset1 = 0;
410 while(1)
412 unsigned int index_in_table_ops, op, rows=0;
413 fill_nbits(reservoir,nbits_in_reservoir,stream,16);
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)
420 reservoir >>= 2;
421 nbits_in_reservoir -= 2;
422 break; /* exit the while(1) */
424 if (op == 0)
426 unsigned int shift;
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] ];
434 if (op == 1)
436 /* 10bits [ xxxx xxxx yyyy 000 ]
437 * yyy => offset in the table8004
438 * xxx => offset in the tabled004
440 unsigned int mask, shift;
441 unsigned int col1, row1, total_bits;
443 offset1 = (offset1 + ((reservoir>>3)&0x0F)+1) & 0x0F;
445 col1 = (reservoir>>7) & 0xFF;
446 row1 = ptable8004 [ offset1*2 ];
448 /* Bit mask table */
449 mask = pdev->table_d004[ (row1<<8) + col1 ];
450 shift = ptable8004 [ offset1*2 + 1];
451 rows = ((mask << shift) + 0x80) & 0xFF;
453 total_bits = row1 + 8;
454 reservoir >>= total_bits;
455 nbits_in_reservoir -= total_bits;
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++)
462 temp_colors[i] += table_a004[ *poffset ];
463 poffset++;
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
475 if (passes == 0)
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;
484 d = dest_y;
485 for (i=0;i<4;i++,c++)
486 *d++ = CLAMP((*c) >> pdev->yy);
488 d = dest_y + bytes_per_channel;
489 for (i=0;i<4;i++,c++)
490 *d++ = CLAMP((*c) >> pdev->yy);
492 d = dest_y + offset_to_plane_u;
493 for (i=0;i<4;i++,c++)
494 *d++ = CLAMP((*c) >> pdev->yy);
496 d = dest_y + offset_to_plane_v;
497 for (i=0;i<4;i++,c++)
498 *d++ = CLAMP((*c) >> pdev->yy);
500 dest_y += 4;
502 else if (passes == 1)
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;
513 d = dest_y;
514 for (i=0;i<4;i++,c1++,c2++)
516 *d++ = CLAMP((*c1) >> pdev->yy);
517 *d++ = CLAMP((*c2) >> pdev->yy);
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++)
524 *d++ = CLAMP((*c1) >> pdev->yy);
525 *d++ = CLAMP((*c2) >> pdev->yy);
528 if (even_line) /* Each line, swap u/v */
530 even_line=0;
531 dest_y = dest_v;
532 dest_u += 8;
534 else
536 even_line=1;
537 dest_y = dest_u;
538 dest_v += 8;
542 } /* end of while (nblocks-->0) */
544 } /* end of for (passes=0;passes<2;passes++) */
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
555 * src: raw data
556 * dst: image output
557 * flags: PWCX_FLAG_PLANAR
558 * pdev: private buffer
559 * bandlength:
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)
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;
576 if (flags & PWCX_FLAG_BAYER)
578 pout = dst + (view->x * offset->y) + offset->x;
579 pixel_size = view->x * 4;
581 else
583 n = view->x * view->y;
585 /* offset in Y plane */
586 stride = view->x * offset->y;
587 pout_planar_y = dst + stride + offset->x;
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;
594 pixel_size = view->x * 4;
598 for (i=0;i<image->y;i+=4)
600 if (flags & PWCX_FLAG_BAYER)
602 //TODO:
603 //DecompressBandBayer(pdev,src,pout,image.x,view->x,flags);
604 src += bandlength;
605 pout += pixel_size;
607 else
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;
618 void pwc_dec23_exit(void)
620 /* Do nothing */