📄 spcadecoder.c
字号:
t1 = tmp[j + 1]; t2 = tmp[j + 2]; t3 = tmp[j + 3]; t4 = tmp[j + 4]; t5 = tmp[j + 5]; t6 = tmp[j + 6]; t7 = tmp[j + 7]; if ((t1 | t2 | t3 | t4 | t5 | t6 | t7) == 0) { te = ITOINT(t0); out[j + 0] = te; out[j + 1] = te; out[j + 2] = te; out[j + 3] = te; out[j + 4] = te; out[j + 5] = te; out[j + 6] = te; out[j + 7] = te; j += 8; continue; } //IDCT; tmp0 = t0 + t1; t1 = t0 - t1; tmp2 = t2 - t3; t3 = t2 + t3; tmp2 = IMULT(tmp2, IC4) - t3; tmp3 = tmp0 + t3; t3 = tmp0 - t3; tmp1 = t1 + tmp2; tmp2 = t1 - tmp2; tmp4 = t4 - t7; t7 = t4 + t7; tmp5 = t5 + t6; t6 = t5 - t6; tmp6 = tmp5 - t7; t7 = tmp5 + t7; tmp5 = IMULT(tmp6, IC4); tmp6 = IMULT((tmp4 + t6), S22); tmp4 = IMULT(tmp4, (C22 - S22)) + tmp6; t6 = IMULT(t6, (C22 + S22)) - tmp6; t6 = t6 - t7; t5 = tmp5 - t6; t4 = tmp4 - t5; out[j + 0] = ITOINT(tmp3 + t7); out[j + 1] = ITOINT(tmp1 + t6); out[j + 2] = ITOINT(tmp2 + t5); out[j + 3] = ITOINT(t3 + t4); out[j + 4] = ITOINT(t3 - t4); out[j + 5] = ITOINT(tmp2 - t5); out[j + 6] = ITOINT(tmp1 - t6); out[j + 7] = ITOINT(tmp3 - t7); j += 8; }}static unsigned char zig[64] = { 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63};static int aaidct[8] = { IFIX(0.3535533906), IFIX(0.4903926402), IFIX(0.4619397663), IFIX(0.4157348062), IFIX(0.3535533906), IFIX(0.2777851165), IFIX(0.1913417162), IFIX(0.0975451610)};inline static void idctqtab(unsigned char *qin, int *qout){ int i, j; for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] * IMULT(aaidct[i], aaidct[j]);}inline static void scaleidctqtab(int *q, int sc){ int i; for (i = 0; i < 64; i++) q[i] = IMULT(q[i], sc);}/* Reduce to the necessary minimum. FIXME */void init_qTable(struct usb_spca50x *spca50x, unsigned int qIndex){ int i, j; /* set up a quantization table */ for (i = 0; i < 2; i++) { for (j = 0; j < 64; j++) { spca50x->maindecode.quant[i][j] = GsmartQTable[qIndex * 2 + i][j]; } } idctqtab(spca50x->maindecode. quant[spca50x->maindecode.dscans[0].tq], spca50x->maindecode.dquant[0]); idctqtab(spca50x->maindecode. quant[spca50x->maindecode.dscans[1].tq], spca50x->maindecode.dquant[1]); idctqtab(spca50x->maindecode. quant[spca50x->maindecode.dscans[2].tq], spca50x->maindecode.dquant[2]); /* rescale qtab */ //scaleidctqtab (spca50x->maindecode.dquant[0], IFIX (0.7)); //scaleidctqtab (spca50x->maindecode.dquant[1], IFIX (0.7)); //scaleidctqtab (spca50x->maindecode.dquant[2], IFIX (0.7)); }void init_jpeg_decoder(struct usb_spca50x *spca50x){ unsigned int i, j, k, l; int tc, th, tt, tac, tdc; unsigned char *ptr; unsigned int qIndex = spca50x->qindex; memcpy(spca50x->maindecode.comps, comp_template, MAXCOMP * sizeof(struct comp)); /* set up the huffman table */ ptr = (unsigned char *) GsmartJPEGHuffmanTable; l = GSMART_JPG_HUFFMAN_TABLE_LENGTH; while (l > 0) { int hufflen[16]; unsigned char huffvals[256]; tc = *ptr++; th = tc & 15; tc >>= 4; tt = tc * 2 + th; if (tc > 1 || th > 1) { //printf("died whilst setting up huffman table.\n"); //abort(); } for (i = 0; i < 16; i++) hufflen[i] = *ptr++; l -= 1 + 16; k = 0; for (i = 0; i < 16; i++) { for (j = 0; j < (unsigned int) hufflen[i]; j++) huffvals[k++] = *ptr++; l -= hufflen[i]; } dec_makehuff(dhuff + tt, hufflen, huffvals); } /* set up the scan table */ ptr = (unsigned char *) GsmartJPEGScanTable; for (i = 0; i < 3; i++) { spca50x->maindecode.dscans[i].cid = *ptr++; tdc = *ptr++; tac = tdc & 15; tdc >>= 4; if (tdc > 1 || tac > 1) { //printf("died whilst setting up scan table.\n"); //abort(); } /* for each component */ for (j = 0; j < 3; j++) if (spca50x->maindecode.comps[j].cid == spca50x->maindecode.dscans[i].cid) break; spca50x->maindecode.dscans[i].hv = spca50x->maindecode.comps[j].hv; spca50x->maindecode.dscans[i].tq = spca50x->maindecode.comps[j].tq; spca50x->maindecode.dscans[i].hudc.dhuff = dec_huffdc + tdc; spca50x->maindecode.dscans[i].huac.dhuff = dec_huffac + tac; } if (spca50x->maindecode.dscans[0].cid != 1 || spca50x->maindecode.dscans[1].cid != 2 || spca50x->maindecode.dscans[2].cid != 3) { //printf("invalid cid found.\n"); //abort(); } if (spca50x->maindecode.dscans[0].hv != 0x22 || spca50x->maindecode.dscans[1].hv != 0x11 || spca50x->maindecode.dscans[2].hv != 0x11) { //printf("invalid hv found.\n"); //abort(); } spca50x->maindecode.dscans[0].next = 6 - 4; spca50x->maindecode.dscans[1].next = 6 - 4 - 1; spca50x->maindecode.dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */ /* 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; /********* in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -