00001
00034 #include <linux/module.h>
00035 #include <linux/init.h>
00036 #include <linux/kernel.h>
00037 #include <linux/errno.h>
00038 #include <linux/slab.h>
00039 #include <linux/kref.h>
00040
00041 #include <linux/usb.h>
00042
00043 #include <media/v4l2-common.h>
00044
00045 #include "stk11xx.h"
00046
00047
00048 void stk11xx_b2rgb24(uint8_t *, uint8_t *,
00049 struct stk11xx_coord *, struct stk11xx_coord *,
00050 const int, const int, const int);
00051 void stk11xx_b2rgb32(uint8_t *, uint8_t *,
00052 struct stk11xx_coord *, struct stk11xx_coord *,
00053 const int, const int, const int);
00054 void stk11xx_b2bgr24(uint8_t *, uint8_t *,
00055 struct stk11xx_coord *, struct stk11xx_coord *,
00056 const int, const int, const int);
00057 void stk11xx_b2bgr32(uint8_t *, uint8_t *,
00058 struct stk11xx_coord *, struct stk11xx_coord *,
00059 const int, const int, const int);
00060
00061 void stk11xx_b2yv12(uint8_t *, uint8_t *,
00062 struct stk11xx_coord *, struct stk11xx_coord *,
00063 const int, const int, const int);
00064
00065
00066 void stk11xx_correct_brightness(uint8_t *, const int, const int,
00067 const int, int);
00068
00069
00079 int stk11xx_decompress(struct usb_stk11xx *dev)
00080 {
00081 int factor;
00082
00083 void *data;
00084 void *image;
00085 struct stk11xx_frame_buf *framebuf;
00086
00087 if (dev == NULL)
00088 return -EFAULT;
00089
00090 framebuf = dev->read_frame;
00091
00092 if (framebuf == NULL)
00093 return -EFAULT;
00094
00095 image = dev->image_data;
00096 image += dev->images[dev->fill_image].offset;
00097
00098 data = framebuf->data;
00099
00100 switch (dev->resolution) {
00101 case STK11XX_80x60:
00102 factor = 8;
00103 break;
00104
00105 case STK11XX_128x96:
00106 factor = 5;
00107 break;
00108
00109 case STK11XX_160x120:
00110 factor = 4;
00111 break;
00112
00113 case STK11XX_213x160:
00114 factor = 3;
00115 break;
00116
00117 case STK11XX_320x240:
00118 factor = 2;
00119 break;
00120
00121 case STK11XX_640x480:
00122 factor = 1;
00123 break;
00124
00125 case STK11XX_800x600:
00126 factor = 1;
00127 break;
00128
00129 case STK11XX_1024x768:
00130 factor = 1;
00131 break;
00132
00133 case STK11XX_1280x1024:
00134 factor = 1;
00135 break;
00136
00137 default:
00138 return -EFAULT;
00139 }
00140
00141
00142 switch (dev->vsettings.palette) {
00143 case STK11XX_PALETTE_RGB24:
00144 stk11xx_b2rgb24(data, image, &dev->image, &dev->view,
00145 dev->vsettings.hflip, dev->vsettings.vflip, factor);
00146 break;
00147
00148 case STK11XX_PALETTE_RGB32:
00149 stk11xx_b2rgb32(data, image, &dev->image, &dev->view,
00150 dev->vsettings.hflip, dev->vsettings.vflip, factor);
00151 break;
00152
00153 case STK11XX_PALETTE_BGR24:
00154 stk11xx_b2bgr24(data, image, &dev->image, &dev->view,
00155 dev->vsettings.hflip, dev->vsettings.vflip, factor);
00156 break;
00157
00158 case STK11XX_PALETTE_BGR32:
00159 stk11xx_b2bgr32(data, image, &dev->image, &dev->view,
00160 dev->vsettings.hflip, dev->vsettings.vflip, factor);
00161 break;
00162 }
00163
00164 stk11xx_correct_brightness(image, dev->view.x, dev->view.y,
00165 dev->vsettings.brightness, dev->vsettings.depth);
00166
00167 return 0;
00168 }
00169
00170
00184 void stk11xx_correct_brightness(uint8_t *rgb, const int width, const int height,
00185 const int brightness, int depth)
00186 {
00187 int i;
00188 int x;
00189
00190 depth = (depth == 24) ? 3 : 4;
00191
00192 if (brightness >= 32767) {
00193 x = (brightness - 32767) / 256;
00194
00195 for (i = 0; i < (width * height * depth); i++) {
00196 if ((*(rgb + i) + (unsigned char) x) > 255)
00197 *(rgb + i) = 255;
00198 else
00199 *(rgb + i) += (unsigned char) x;
00200 }
00201 }
00202 else {
00203 x = (32767 - brightness) / 256;
00204
00205 for (i = 0; i < (width * height * depth); i++) {
00206 if ((unsigned char) x > *(rgb + i))
00207 *(rgb + i) = 0;
00208 else
00209 *(rgb + i) -= (unsigned char) x;
00210 }
00211 }
00212 }
00213
00214
00227 void stk11xx_b2rgb24(uint8_t *bayer, uint8_t *rgb,
00228 struct stk11xx_coord *image,
00229 struct stk11xx_coord *view,
00230 const int hflip, const int vflip,
00231 const int factor) {
00232 uint8_t *b;
00233
00234 int x, y;
00235 int i, j;
00236
00237 int width = image->x;
00238 int height = image->y;
00239
00240 int nwidth = width / factor;
00241 int nheight = height / factor;
00242
00243 int offset;
00244 int startx, stepx;
00245 int starty, stepy;
00246
00247
00248
00249 if (vflip) {
00250 starty = height - 2;
00251 stepy = -factor;
00252 }
00253 else {
00254 starty = 0;
00255 stepy = factor;
00256 }
00257
00258
00259 if (hflip) {
00260 startx = width - 1;
00261 stepx = -factor;
00262 offset = width - 2;
00263 }
00264 else {
00265 startx = 0;
00266 stepx = factor;
00267 offset = 1;
00268 }
00269
00270
00271
00272 bayer += width;
00273
00274
00275 rgb += ((view->y - nheight) / 2) * view->x * 3;
00276
00277
00278 rgb += ((view->x - nwidth) / 2) * 3;
00279
00280
00281 memset(rgb, 0, nwidth * 3);
00282 rgb += nwidth * 3;
00283
00284
00285
00286 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
00287
00288 b = bayer + y * width + offset;
00289
00290
00291 rgb += (view->x - nwidth) * 3;
00292
00293 if (y & 0x1) {
00294
00295 *rgb++ = 0;
00296 *rgb++ = 0;
00297 *rgb++ = 0;
00298
00299
00300 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00301 if (x & 0x1) {
00302 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00303 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00304 *rgb++ = *b;
00305 }
00306 else {
00307 *rgb++ = (*(b-width) + *(b+width)) >> 1;
00308 *rgb++ = *b;
00309 *rgb++ = (*(b-1) + *(b+1)) >> 1;
00310 }
00311
00312 b += stepx;
00313 }
00314
00315
00316 *rgb++ = 0;
00317 *rgb++ = 0;
00318 *rgb++ = 0;
00319 }
00320 else {
00321
00322 *rgb++ = 0;
00323 *rgb++ = 0;
00324 *rgb++ = 0;
00325
00326
00327 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00328 if (x & 0x1) {
00329 *rgb++ = (*(b-1) + *(b+1)) >> 1;
00330 *rgb++ = *b;
00331 *rgb++ = (*(b-width) + *(b+width)) >> 1;
00332 }
00333 else {
00334 *rgb++ = *b;
00335 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00336 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00337 }
00338
00339 b += stepx;
00340 }
00341
00342
00343 *rgb++ = 0;
00344 *rgb++ = 0;
00345 *rgb++ = 0;
00346 }
00347 }
00348
00349
00350 memset(rgb, 0, nwidth * 3);
00351 }
00352
00353
00366 void stk11xx_b2rgb32(uint8_t *bayer, uint8_t *rgb,
00367 struct stk11xx_coord *image,
00368 struct stk11xx_coord *view,
00369 const int hflip, const int vflip,
00370 const int factor) {
00371 uint8_t *b;
00372
00373 int x, y;
00374 int i, j;
00375
00376 int width = image->x;
00377 int height = image->y;
00378
00379 int nwidth = width / factor;
00380 int nheight = height / factor;
00381
00382 int offset;
00383 int startx, stepx;
00384 int starty, stepy;
00385
00386
00387
00388 if (vflip) {
00389 starty = height - 2;
00390 stepy = -factor;
00391 }
00392 else {
00393 starty = 0;
00394 stepy = factor;
00395 }
00396
00397
00398 if (hflip) {
00399 startx = width - 1;
00400 stepx = -factor;
00401 offset = width - 2;
00402 }
00403 else {
00404 startx = 0;
00405 stepx = factor;
00406 offset = 1;
00407 }
00408
00409
00410
00411 bayer += width;
00412
00413
00414 rgb += ((view->y - nheight) / 2) * view->x * 4;
00415
00416
00417 rgb += ((view->x - nwidth) / 2) * 4;
00418
00419
00420 memset(rgb, 0, nwidth * 4);
00421 rgb += nwidth * 4;
00422
00423
00424
00425 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
00426
00427 b = bayer + y * width + offset;
00428
00429
00430 rgb += (view->x - nwidth) * 4;
00431
00432 if (y & 0x1) {
00433
00434 *rgb++ = 0;
00435 *rgb++ = 0;
00436 *rgb++ = 0;
00437 *rgb++ = 0;
00438
00439
00440 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00441 if (x & 0x1) {
00442 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00443 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00444 *rgb++ = *b;
00445 *rgb++ = 0;
00446 }
00447 else {
00448 *rgb++ = (*(b-width) + *(b+width)) >> 1;
00449 *rgb++ = *b;
00450 *rgb++ = (*(b-1) + *(b+1)) >> 1;
00451 *rgb++ = 0;
00452 }
00453
00454 b += stepx;
00455 }
00456
00457
00458 *rgb++ = 0;
00459 *rgb++ = 0;
00460 *rgb++ = 0;
00461 *rgb++ = 0;
00462 }
00463 else {
00464
00465 *rgb++ = 0;
00466 *rgb++ = 0;
00467 *rgb++ = 0;
00468 *rgb++ = 0;
00469
00470
00471 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00472 if (x & 0x1) {
00473 *rgb++ = (*(b-1) + *(b+1)) >> 1;
00474 *rgb++ = *b;
00475 *rgb++ = (*(b-width) + *(b+width)) >> 1;
00476 *rgb++ = 0;
00477 }
00478 else {
00479 *rgb++ = *b;
00480 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00481 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00482 *rgb++ = 0;
00483 }
00484
00485 b += stepx;
00486 }
00487
00488
00489 *rgb++ = 0;
00490 *rgb++ = 0;
00491 *rgb++ = 0;
00492 *rgb++ = 0;
00493 }
00494 }
00495
00496
00497 memset(rgb, 0, nwidth * 4);
00498 }
00499
00500
00513 void stk11xx_b2bgr24(uint8_t *bayer, uint8_t *bgr,
00514 struct stk11xx_coord *image,
00515 struct stk11xx_coord *view,
00516 const int hflip, const int vflip,
00517 const int factor) {
00518 uint8_t *b;
00519
00520 int x, y;
00521 int i, j;
00522
00523 int width = image->x;
00524 int height = image->y;
00525
00526 int nwidth = width / factor;
00527 int nheight = height / factor;
00528
00529 int offset;
00530 int startx, stepx;
00531 int starty, stepy;
00532
00533
00534
00535 if (vflip) {
00536 starty = height - 2;
00537 stepy = -factor;
00538 }
00539 else {
00540 starty = 0;
00541 stepy = factor;
00542 }
00543
00544
00545 if (hflip) {
00546 startx = width - 1;
00547 stepx = -factor;
00548 offset = width - 2;
00549 }
00550 else {
00551 startx = 0;
00552 stepx = factor;
00553 offset = 1;
00554 }
00555
00556
00557
00558 bayer += width;
00559
00560
00561 bgr += ((view->y - nheight) / 2) * view->x * 3;
00562
00563
00564 bgr += ((view->x - nwidth) / 2) * 3;
00565
00566
00567 memset(bgr, 0, nwidth * 3);
00568 bgr += nwidth * 3;
00569
00570
00571
00572 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
00573
00574 b = bayer + y * width + offset;
00575
00576
00577 bgr += (view->x - nwidth) * 3;
00578
00579 if (y & 0x1) {
00580
00581 *bgr++ = 0;
00582 *bgr++ = 0;
00583 *bgr++ = 0;
00584
00585
00586 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00587 if (x & 0x1) {
00588 *bgr++ = *b;
00589 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00590 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00591 }
00592 else {
00593 *bgr++ = (*(b-1) + *(b+1)) >> 1;
00594 *bgr++ = *b;
00595 *bgr++ = (*(b-width) + *(b+width)) >> 1;
00596 }
00597
00598 b += stepx;
00599 }
00600
00601
00602 *bgr++ = 0;
00603 *bgr++ = 0;
00604 *bgr++ = 0;
00605 }
00606 else {
00607
00608 *bgr++ = 0;
00609 *bgr++ = 0;
00610 *bgr++ = 0;
00611
00612
00613 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00614 if (x & 0x1) {
00615 *bgr++ = (*(b-width) + *(b+width)) >> 1;
00616 *bgr++ = *b;
00617 *bgr++ = (*(b-1) + *(b+1)) >> 1;
00618 }
00619 else {
00620 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00621 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00622 *bgr++ = *b;
00623 }
00624
00625 b += stepx;
00626 }
00627
00628
00629 *bgr++ = 0;
00630 *bgr++ = 0;
00631 *bgr++ = 0;
00632 }
00633 }
00634
00635
00636 memset(bgr, 0, nwidth * 3);
00637 }
00638
00639
00652 void stk11xx_b2bgr32(uint8_t *bayer, uint8_t *bgr,
00653 struct stk11xx_coord *image,
00654 struct stk11xx_coord *view,
00655 const int hflip, const int vflip,
00656 const int factor) {
00657 uint8_t *b;
00658
00659 int x, y;
00660 int i, j;
00661
00662 int width = image->x;
00663 int height = image->y;
00664
00665 int nwidth = width / factor;
00666 int nheight = height / factor;
00667
00668 int offset;
00669 int startx, stepx;
00670 int starty, stepy;
00671
00672
00673
00674 if (vflip) {
00675 starty = height - 2;
00676 stepy = -factor;
00677 }
00678 else {
00679 starty = 0;
00680 stepy = factor;
00681 }
00682
00683
00684 if (hflip) {
00685 startx = width - 1;
00686 stepx = -factor;
00687 offset = width - 2;
00688 }
00689 else {
00690 startx = 0;
00691 stepx = factor;
00692 offset = 1;
00693 }
00694
00695
00696
00697 bayer += width;
00698
00699
00700 bgr += ((view->y - nheight) / 2) * view->x * 4;
00701
00702
00703 bgr += ((view->x - nwidth) / 2) * 4;
00704
00705
00706 memset(bgr, 0, nwidth * 4);
00707 bgr += nwidth * 4;
00708
00709
00710
00711 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
00712
00713 b = bayer + y * width + offset;
00714
00715
00716 bgr += (view->x - nwidth) * 4;
00717
00718 if (y & 0x1) {
00719
00720 *bgr++ = 0;
00721 *bgr++ = 0;
00722 *bgr++ = 0;
00723 *bgr++ = 0;
00724
00725
00726 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00727 if (x & 0x1) {
00728 *bgr++ = *b;
00729 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00730 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00731 *bgr++ = 0;
00732 }
00733 else {
00734 *bgr++ = (*(b-1) + *(b+1)) >> 1;
00735 *bgr++ = *b;
00736 *bgr++ = (*(b-width) + *(b+width)) >> 1;
00737 *bgr++ = 0;
00738 }
00739
00740 b += stepx;
00741 }
00742
00743
00744 *bgr++ = 0;
00745 *bgr++ = 0;
00746 *bgr++ = 0;
00747 *bgr++ = 0;
00748 }
00749 else {
00750
00751 *bgr++ = 0;
00752 *bgr++ = 0;
00753 *bgr++ = 0;
00754 *bgr++ = 0;
00755
00756
00757 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
00758 if (x & 0x1) {
00759 *bgr++ = (*(b-width) + *(b+width)) >> 1;
00760 *bgr++ = *b;
00761 *bgr++ = (*(b-1) + *(b+1)) >> 1;
00762 *bgr++ = 0;
00763 }
00764 else {
00765 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
00766 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
00767 *bgr++ = *b;
00768 *bgr++ = 0;
00769 }
00770
00771 b += stepx;
00772 }
00773
00774
00775 *bgr++ = 0;
00776 *bgr++ = 0;
00777 *bgr++ = 0;
00778 *bgr++ = 0;
00779 }
00780 }
00781
00782
00783 memset(bgr, 0, nwidth * 4);
00784 }
00785
00786
00799 void stk11xx_b2yv12(uint8_t *bayer, uint8_t *yuv,
00800 struct stk11xx_coord *image,
00801 struct stk11xx_coord *view,
00802 const int hflip, const int vflip,
00803 const int factor) {
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 }
00926
00927