📄 spcadecoder.c
字号:
/* set up a quantization table */ init_qTable(spca50x, qIndex);}static int bgr = 0;/* Gamma correction setting *//* Gtable[0][n] -> 2.2* Gtable[1][n] -> 1.7* Gtable[2][n] -> 1.45* Gtable[3][n] -> 1* Gtable[4][n] -> 0.6896* Gtable[5][n] -> 0.5882* Gtable[6][n] -> 0.4545* gCor coeff 0..6*/int spca50x_outpicture(struct spca50x_frame *myframe){ /* general idea keep a frame in the temporary buffer from the tasklet */ /* decode with native format at input and asked format at output */ /* myframe->cameratype is the native input format */ /* myframe->format is the asked format */ struct pictparam *gCorrect = &myframe->pictsetting; unsigned char *red = myframe->decoder->Red; unsigned char *green = myframe->decoder->Green; unsigned char *blue = myframe->decoder->Blue; int width = 0; int height = 0; int done = 0; int i; if (gCorrect->change) { if (gCorrect->change == 0x01) { /* Gamma setting change compute all case */ memcpy(red, >able[gCorrect->gamma], 256); memcpy(green, >able[gCorrect->gamma], 256); memcpy(blue, >able[gCorrect->gamma], 256); for (i = 0; i < 256; i++) { red[i] = CLIP(((red[i] + gCorrect->OffRed) * gCorrect->GRed) >> 8); green[i] = CLIP(((green[i] + gCorrect->OffGreen) * gCorrect->GGreen) >> 8); blue[i] = CLIP(((blue[i] + gCorrect->OffBlue) * gCorrect->GBlue) >> 8); } bgr = gCorrect->force_rgb; gCorrect->change = 0x00; } if (gCorrect->change == 0x02) { /* Red setting change compute Red Value */ memcpy(red, >able[gCorrect->gamma], 256); for (i = 0; i < 256; i++) { red[i] = CLIP(((red[i] + gCorrect->OffRed) * gCorrect->GRed) >> 8); } gCorrect->change &= ~0x02; } if (gCorrect->change == 0x04) { /* Green setting change compute Green Value */ memcpy(green, >able[gCorrect->gamma], 256); for (i = 0; i < 256; i++) { green[i] = CLIP(((green[i] + gCorrect->OffGreen) * gCorrect->GGreen) >> 8); } gCorrect->change &= ~0x04; } if (gCorrect->change == 0x08) { /* Blue setting change compute Blue Value */ memcpy(blue, >able[gCorrect->gamma], 256); for (i = 0; i < 256; i++) { blue[i] = CLIP(((blue[i] + gCorrect->OffBlue) * gCorrect->GBlue) >> 8); } gCorrect->change &= ~0x08; } if (gCorrect->change == 0x10) { /* force_rgb setting change */ bgr = gCorrect->force_rgb; gCorrect->change &= ~0x10; } } switch (myframe->cameratype) { case JPGC: height = (myframe->data[11] << 8) | myframe->data[12]; width = (myframe->data[13] << 8) | myframe->data[14]; if (myframe->hdrheight != height || myframe->hdrwidth != width) done = ERR_CORRUPTFRAME; else { //set info.dri struct should be kmalloc with the // instance camera myframe->decoder->info.dri = myframe->data[5]; if (myframe->format == VIDEO_PALETTE_JPEG) { memcpy(myframe->tmpbuffer, myframe->data, myframe->scanlength); done = make_jpeg_conexant(myframe); } else { memcpy(myframe->tmpbuffer, myframe->data + 39, myframe->scanlength - 39); done = jpeg_decode422(myframe, bgr); } } break; case JPGH: width = (myframe->data[10] << 8) | myframe->data[11]; height = (myframe->data[12] << 8) | myframe->data[13]; /* some camera did not respond with the good height ie:Labtec Pro 240 -> 232 */ if (myframe->hdrwidth != width) done = ERR_CORRUPTFRAME; else { // reset info.dri myframe->decoder->info.dri = 0; memcpy(myframe->tmpbuffer, myframe->data + 16, myframe->scanlength - 16); if (myframe->format == VIDEO_PALETTE_JPEG) done = make_jpeg(myframe); else done = jpeg_decode422(myframe, bgr); } break; case JPGM: case JPGS: // reset info.dri myframe->decoder->info.dri = 0; memcpy(myframe->tmpbuffer, myframe->data, myframe->scanlength); if (myframe->format == VIDEO_PALETTE_JPEG) done = make_jpeg(myframe); else done = jpeg_decode422(myframe, bgr); break; case JPEG: memcpy(myframe->tmpbuffer, myframe->data, myframe->scanlength); if (myframe->format == VIDEO_PALETTE_JPEG) done = make_jpeg(myframe); else done = jpeg_decode411(myframe, bgr); break; case YUVY: case YUYV: case YYUV: memcpy(myframe->tmpbuffer, myframe->data, myframe->scanlength); done = yuv_decode(myframe, bgr); break; case PGBRG: done = pixart_decompress(myframe); if (done < 0) break; done = bayer_decode(myframe, bgr); break; case GBGR: /* translate the tv8532 stream into GBRG stream */ tv8532_preprocess(myframe); done = bayer_decode(myframe, bgr); break; case GBRG: memcpy(myframe->tmpbuffer, myframe->data, myframe->scanlength); done = bayer_decode(myframe, bgr); break; case S561: if (myframe->data[1] & 0x10) decode_spca561(myframe->data, myframe->tmpbuffer, myframe->width, myframe->height); else memcpy(myframe->tmpbuffer, myframe->data + 20, myframe->scanlength); done = bayer_decode(myframe, bgr); break; case SN9C: sonix_decompress(myframe); done = bayer_decode(myframe, bgr); break; default: done = -1; break; } return done;}static int yuv_decode(struct spca50x_frame *myframe, int force_rgb){ int r_offset, g_offset, b_offset; int my, mx; /* scan input surface */ unsigned char *pic1; /* output surface */ __u16 *pix1, *pix2; /* same for 16 bits output */ unsigned char *U, *V; /* chroma output pointer */ int inuv, inv, pocx; /* offset chroma input */ int iny, iny1; /* offset luma input */ int nextinline, nextoutline; int u1, v1, rg; unsigned char y, y1; char u, v; unsigned char *pic = myframe->data; /* output surface */ unsigned char *buf = myframe->tmpbuffer; /* input surface */ int width = myframe->hdrwidth; int height = myframe->hdrheight; int softwidth = myframe->width; int softheight = myframe->height; //int method = myframe->method; int format = myframe->format; int cropx1 = myframe->cropx1; int cropx2 = myframe->cropx2; int cropy1 = myframe->cropy1; int cropy2 = myframe->cropy2; unsigned char *red = myframe->decoder->Red; unsigned char *green = myframe->decoder->Green; unsigned char *blue = myframe->decoder->Blue; int bpp; int framesize, frameUsize; framesize = softwidth * softheight; frameUsize = framesize >> 2; /* rgb or bgr like U or V that's the question */ if (force_rgb) { U = pic + framesize; V = U + frameUsize; r_offset = 2; g_offset = 1; b_offset = 0; } else { V = pic + framesize; U = V + frameUsize; r_offset = 0; g_offset = 1; b_offset = 2; } switch (myframe->cameratype) { case YUVY:{ iny = 0; /********* iny **********/ inuv = width; /*** inuv **** inv ******/ nextinline = 3 * width; inv = (nextinline >> 1); iny1 = width << 1; /********* iny1 *********/ } break; case YUYV:{ iny = 0; /********* iny **********/ inuv = width; /*** inuv **** iny1 *****/ nextinline = 3 * width; iny1 = (nextinline >> 1); inv = iny1 + width; /*** iny1 **** inv ******/ } break; case YYUV:{ iny = 0; /********* iny **********/ iny1 = width; /********* iny1 *********/ inuv = width << 1; /*** inuv **** inv ******/ inv = inuv + (width >> 1); nextinline = 3 * width; } break; default:{ iny = 0; /* make compiler happy */ iny1 = 0; inuv = 0; inv = 0; nextinline = 0; } break; } /* Decode to the correct format. */ switch (format) { case VIDEO_PALETTE_RGB565: { bpp = 2; /* initialize */ pix1 = (__u16 *) pic; pix2 = pix1 + softwidth; for (my = 0; my < height; my += 2) { for (mx = 0, pocx = 0; mx < width; mx += 2, pocx++) { /* test if we need to decode */ if ((my >= cropy1) && (my < height - cropy2) && (mx >= cropx1) && (mx < width - cropx2)) { /* yes decode */ if (force_rgb) { u = buf[inuv + pocx]; v = buf[inv + pocx]; } else { v = buf[inuv + pocx]; u = buf[inv + pocx]; } v1 = ((v << 10) + (v << 9)) >> 10; rg = ((u << 8) + (u << 7) + (v << 9) + (v << 4)) >> 10; u1 = ((u << 11) + (u << 4)) >> 10; /* top pixel Right */ y1 = 128 + buf[iny + mx]; *pix1++ = ((red[CLIP((y1 + v1))] & 0xF8) >> 3 | ((green [CLIP((y1 - rg))] & 0xFC) << 3) | ((blue [CLIP((y1 + u1))] & 0xF8) << 8)); /* top pixel Left */ y1 = 128 + buf[iny + mx + 1]; *pix1++ = ((red[CLIP((y1 + v1))] & 0xF8) >> 3 | ((green [CLIP((y1 - rg))] & 0xFC) << 3) | ((blue [CLIP((y1 + u1))] & 0xF8) << 8)); /* bottom pixel Right */ y1 = 128 + buf[iny1 + mx]; *pix2++ = ((red[CLIP((y1 + v1))] & 0xF8) >> 3 | ((green [CLIP((y1 - rg))] & 0xFC) << 3) | ((blue [CLIP((y1 + u1))] & 0xF8) << 8)); /* bottom pixel Left */ y1 = 128 + buf[iny1 + mx + 1]; *pix2++ = ((red[CLIP((y1 + v1))] & 0xF8) >> 3 | ((green [CLIP((y1 - rg))] & 0xFC) << 3) | ((blue [CLIP((y1 + u1))] & 0xF8) << 8)); } // end test decode } // end mx loop iny += nextinline; inuv += nextinline; inv += nextinline; iny1 += nextinline; if (my >= cropy1) { /* are we in a decode surface move the output pointer */ pix1 += softwidth; pix2 += softwidth; } } // end my loop } myframe->scanlength = (long) (softwidth * softheight * bpp); break; case VIDEO_PALETTE_RGB32: case VIDEO_PALETTE_RGB24: { bpp = (format == VIDEO_PALETTE_RGB32) ? 4 : 3; /* initialize */ nextoutline = bpp * softwidth; pic1 = pic + nextoutline; for (my = 0; my < height; my += 2) { for (mx = 0, pocx = 0; mx < width; mx += 2, pocx++) { /* test if we need to decode */ if ((my >= cropy1) && (my < height - cropy2) && (mx >= cropx1) && (mx < width - cropx2)) { /* yes decode */ v = buf[inuv + pocx]; u = buf[inv + pocx]; v1 = ((v << 10) + (v << 9)) >> 10; rg = ((u << 8) + (u << 7) + (v << 9) + (v << 4)) >> 10; u1 = ((u << 11) + (u << 4)) >> 10; y = 128 + buf[iny + mx]; /* top pixel Right */ pic[r_offset] = red[CLIP((y + v1))]; pic[g_offset] = green[CLIP((y - rg))]; pic[b_offset] = blue[CLIP((y + u1))]; pic += bpp; /* top pixel Left */ y = 128 + buf[iny + mx + 1]; pic[r_offset] = r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -