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