📄 readjpg.c
字号:
break; code <<= 1; m >>= 1; if(m == 0){ t->shift[v] = 0; t->value[v] = -1; goto continueBytes; } cnt--; } t->shift[v] = 8-cnt; t->value[v] = t->val[t->valptr[i]+(code-t->mincode[i])]; continueBytes: v++; } return nsize;}staticvoidhuffmantables(Header *h, uchar *b, int n){ int l, mt; for(l=0; l<n; l+=17+mt) mt = huffmantable(h, &b[l]);}staticintquanttable(Header *h, uchar *b){ int i, pq, tq, *q; nibbles(b[0], &pq, &tq); if(pq > 1) jpgerror(h, "ReadJPG: unknown quantization table class %d", pq); if(tq > 3) jpgerror(h, "ReadJPG: unknown quantization table index %d", tq); q = h->qt[tq]; for(i=0; i<64; i++){ if(pq == 0) q[i] = b[1+i]; else q[i] = int2(b, 1+2*i); } return 64*(1+pq);}staticvoidquanttables(Header *h, uchar *b, int n){ int l, m; for(l=0; l<n; l+=1+m) m = quanttable(h, &b[l]);}staticRawimage*baselinescan(Header *h, int colorspace){ int Ns, z, k, m, Hmax, Vmax, comp; int allHV1, nblock, ri, mcu, nacross, nmcu; Huffman *dcht, *acht; int block, t, diff, *qt; uchar *ss; Rawimage *image; int Td[3], Ta[3], H[3], V[3], DC[3]; int ***data, *zz; ss = h->ss; Ns = ss[0]; if((Ns!=3 && Ns!=1) || Ns!=h->Nf) jpgerror(h, "ReadJPG: can't handle scan not 3 components"); image = jpgmalloc(h, sizeof(Rawimage), 1); h->image = image; image->r = Rect(0, 0, h->X, h->Y); image->cmap = nil; image->cmaplen = 0; image->chanlen = h->X*h->Y; image->fields = 0; image->gifflags = 0; image->gifdelay = 0; image->giftrindex = 0; if(Ns == 3) image->chandesc = colorspace; else image->chandesc = CY; image->nchans = h->Nf; for(k=0; k<h->Nf; k++) image->chans[k] = jpgmalloc(h, h->X*h->Y, 0); /* compute maximum H and V */ Hmax = 0; Vmax = 0; for(comp=0; comp<Ns; comp++){ if(h->comp[comp].H > Hmax) Hmax = h->comp[comp].H; if(h->comp[comp].V > Vmax) Vmax = h->comp[comp].V; } /* initialize data structures */ allHV1 = 1; data = h->data; for(comp=0; comp<Ns; comp++){ /* JPEG requires scan components to be in same order as in frame, */ /* so if both have 3 we know scan is Y Cb Cr and there's no need to */ /* reorder */ nibbles(ss[2+2*comp], &Td[comp], &Ta[comp]); H[comp] = h->comp[comp].H; V[comp] = h->comp[comp].V; nblock = H[comp]*V[comp]; if(nblock != 1) allHV1 = 0; data[comp] = jpgmalloc(h, nblock*sizeof(int*), 0); h->ndata[comp] = nblock; DC[comp] = 0; for(m=0; m<nblock; m++) data[comp][m] = jpgmalloc(h, 8*8*sizeof(int), 0); } ri = h->ri; h->cnt = 0; h->sr = 0; h->peek = -1; nacross = ((h->X+(8*Hmax-1))/(8*Hmax)); nmcu = ((h->Y+(8*Vmax-1))/(8*Vmax))*nacross; for(mcu=0; mcu<nmcu; ){ for(comp=0; comp<Ns; comp++){ dcht = &h->dcht[Td[comp]]; acht = &h->acht[Ta[comp]]; qt = h->qt[h->comp[comp].Tq]; for(block=0; block<H[comp]*V[comp]; block++){ /* F-22 */ t = decode(h, dcht); diff = receive(h, t); DC[comp] += diff; /* F-23 */ zz = data[comp][block]; memset(zz, 0, 8*8*sizeof(int)); zz[0] = qt[0]*DC[comp]; k = 1; for(;;){ t = decode(h, acht); if((t&0x0F) == 0){ if((t&0xF0) != 0xF0) break; k += 16; }else{ k += t>>4; z = receive(h, t&0xF); zz[zig[k]] = z*qt[k]; if(k == 63) break; k++; } } idct(zz); } } /* rotate colors to RGB and assign to bytes */ if(Ns == 1) /* very easy */ colormap1(h, colorspace, image, data[0][0], mcu, nacross); else if(allHV1) /* fairly easy */ colormapall1(h, colorspace, image, data[0][0], data[1][0], data[2][0], mcu, nacross); else /* miserable general case */ colormap(h, colorspace, image, data[0], data[1], data[2], mcu, nacross, Hmax, Vmax, H, V); /* process restart marker, if present */ mcu++; if(ri>0 && mcu<nmcu && mcu%ri==0){ restart(h, mcu); for(comp=0; comp<Ns; comp++) DC[comp] = 0; } } return image;}staticvoidrestart(Header *h, int mcu){ int rest, rst, nskip; rest = mcu/h->ri-1; nskip = 0; do{ do{ rst = nextbyte(h, 1); nskip++; }while(rst>=0 && rst!=0xFF); if(rst == 0xFF){ rst = nextbyte(h, 1); nskip++; } }while(rst>=0 && (rst&~7)!=RST); if(nskip != 2) sprint(h->err, "ReadJPG: skipped %d bytes at restart %d\n", nskip-2, rest); if(rst < 0) jpgerror(h, readerr); if((rst&7) != (rest&7)) jpgerror(h, "ReadJPG: expected RST%d got %d", rest&7, rst&7); h->cnt = 0; h->sr = 0;}staticRawimage*progressiveIDCT(Header *h, int colorspace){ int k, m, comp, block, Nf, bn; int allHV1, nblock, mcu, nmcu; int H[3], V[3], blockno[3]; int *dccoeff, **accoeff; int ***data, *zz; Nf = h->Nf; allHV1 = 1; data = h->data; for(comp=0; comp<Nf; comp++){ H[comp] = h->comp[comp].H; V[comp] = h->comp[comp].V; nblock = h->nblock[comp]; if(nblock != 1) allHV1 = 0; h->ndata[comp] = nblock; data[comp] = jpgmalloc(h, nblock*sizeof(int*), 0); for(m=0; m<nblock; m++) data[comp][m] = jpgmalloc(h, 8*8*sizeof(int), 0); } memset(blockno, 0, sizeof blockno); nmcu = h->nacross*h->ndown; for(mcu=0; mcu<nmcu; mcu++){ for(comp=0; comp<Nf; comp++){ dccoeff = h->dccoeff[comp]; accoeff = h->accoeff[comp]; bn = blockno[comp]; for(block=0; block<h->nblock[comp]; block++){ zz = data[comp][block]; memset(zz, 0, 8*8*sizeof(int)); zz[0] = dccoeff[bn]; for(k=1; k<64; k++) zz[zig[k]] = accoeff[bn][k]; idct(zz); bn++; } blockno[comp] = bn; } /* rotate colors to RGB and assign to bytes */ if(Nf == 1) /* very easy */ colormap1(h, colorspace, h->image, data[0][0], mcu, h->nacross); else if(allHV1) /* fairly easy */ colormapall1(h, colorspace, h->image, data[0][0], data[1][0], data[2][0], mcu, h->nacross); else /* miserable general case */ colormap(h, colorspace, h->image, data[0], data[1], data[2], mcu, h->nacross, h->Hmax, h->Vmax, H, V); } return h->image;}staticvoidprogressiveinit(Header *h, int colorspace){ int Nf, Ns, j, k, nmcu, comp; uchar *ss; Rawimage *image; ss = h->ss; Ns = ss[0]; Nf = h->Nf; if((Ns!=3 && Ns!=1) || Ns!=Nf) jpgerror(h, "ReadJPG: image must have 1 or 3 components"); image = jpgmalloc(h, sizeof(Rawimage), 1); h->image = image; image->r = Rect(0, 0, h->X, h->Y); image->cmap = nil; image->cmaplen = 0; image->chanlen = h->X*h->Y; image->fields = 0; image->gifflags = 0; image->gifdelay = 0; image->giftrindex = 0; if(Nf == 3) image->chandesc = colorspace; else image->chandesc = CY; image->nchans = h->Nf; for(k=0; k<Nf; k++){ image->chans[k] = jpgmalloc(h, h->X*h->Y, 0); h->nblock[k] = h->comp[k].H*h->comp[k].V; } /* compute maximum H and V */ h->Hmax = 0; h->Vmax = 0; for(comp=0; comp<Nf; comp++){ if(h->comp[comp].H > h->Hmax) h->Hmax = h->comp[comp].H; if(h->comp[comp].V > h->Vmax) h->Vmax = h->comp[comp].V; } h->nacross = ((h->X+(8*h->Hmax-1))/(8*h->Hmax)); h->ndown = ((h->Y+(8*h->Vmax-1))/(8*h->Vmax)); nmcu = h->nacross*h->ndown; for(k=0; k<Nf; k++){ h->dccoeff[k] = jpgmalloc(h, h->nblock[k]*nmcu * sizeof(int), 1); h->accoeff[k] = jpgmalloc(h, h->nblock[k]*nmcu * sizeof(int*), 1); h->naccoeff[k] = h->nblock[k]*nmcu; for(j=0; j<h->nblock[k]*nmcu; j++) h->accoeff[k][j] = jpgmalloc(h, 64*sizeof(int), 1); }}staticvoidprogressivedc(Header *h, int comp, int Ah, int Al){ int Ns, z, ri, mcu, nmcu; int block, t, diff, qt, *dc, bn; Huffman *dcht; uchar *ss; int Td[3], DC[3], blockno[3]; ss= h->ss; Ns = ss[0]; if(Ns!=h->Nf) jpgerror(h, "ReadJPG: can't handle progressive with Nf!=Ns in DC scan"); /* initialize data structures */ h->cnt = 0; h->sr = 0; h->peek = -1; for(comp=0; comp<Ns; comp++){ /* * JPEG requires scan components to be in same order as in frame, * so if both have 3 we know scan is Y Cb Cr and there's no need to * reorder */ nibbles(ss[2+2*comp], &Td[comp], &z); /* z is ignored */ DC[comp] = 0; } ri = h->ri; nmcu = h->nacross*h->ndown; memset(blockno, 0, sizeof blockno); for(mcu=0; mcu<nmcu; ){ for(comp=0; comp<Ns; comp++){ dcht = &h->dcht[Td[comp]]; qt = h->qt[h->comp[comp].Tq][0]; dc = h->dccoeff[comp]; bn = blockno[comp]; for(block=0; block<h->nblock[comp]; block++){ if(Ah == 0){ t = decode(h, dcht); diff = receive(h, t); DC[comp] += diff; dc[bn] = qt*DC[comp]<<Al; }else dc[bn] |= qt*receivebit(h)<<Al; bn++; } blockno[comp] = bn; } /* process restart marker, if present */ mcu++; if(ri>0 && mcu<nmcu && mcu%ri==0){ restart(h, mcu); for(comp=0; comp<Ns; comp++) DC[comp] = 0; } }}staticvoidprogressiveac(Header *h, int comp, int Al){ int Ns, Ss, Se, z, k, eobrun, x, y, nver, tmcu, blockno, *acc, rs; int ri, mcu, nacross, ndown, nmcu, nhor; Huffman *acht; int *qt, rrrr, ssss, q; uchar *ss; int Ta, H, V; ss = h->ss; Ns = ss[0]; if(Ns != 1) jpgerror(h, "ReadJPG: illegal Ns>1 in progressive AC scan"); Ss = ss[1+2]; Se = ss[2+2]; H = h->comp[comp].H; V = h->comp[comp].V; nacross = h->nacross*H; ndown = h->ndown*V; q = 8*h->Hmax/H; nhor = (h->X+q-1)/q; q = 8*h->Vmax/V; nver = (h->Y+q-1)/q; /* initialize data structures */ h->cnt = 0; h->sr = 0; h->peek = -1; nibbles(ss[1+1], &z, &Ta); /* z is thrown away */ ri = h->ri; eobrun = 0; acht = &h->acht[Ta]; qt = h->qt[h->comp[comp].Tq]; nmcu = nacross*ndown; mcu = 0; for(y=0; y<nver; y++){ for(x=0; x<nhor; x++){ /* Figure G-3 */ if(eobrun > 0){ --eobrun; continue; } /* arrange blockno to be in same sequence as original scan calculation. */ tmcu = x/H + (nacross/H)*(y/V); blockno = tmcu*H*V + H*(y%V) + x%H; acc = h->accoeff[comp][blockno]; k = Ss; for(;;){ rs = decode(h, acht); /* XXX remove rrrr ssss as in baselinescan */ nibbles(rs, &rrrr, &ssss); if(ssss == 0){ if(rrrr < 15){ eobrun = 0; if(rrrr > 0) eobrun = receiveEOB(h, rrrr)-1; break; } k += 16; }else{ k += rrrr; z = receive(h, ssss); acc[k] = z*qt[k]<<Al; if(k == Se) break; k++; } } } /* process restart marker, if present */ mcu++; if(ri>0 && mcu<nmcu && mcu%ri==0){ restart(h, mcu); eobrun = 0; } }}staticvoidincrement(Header *h, int acc[], int k, int Pt){ if(acc[k] == 0) return; if(receivebit(h) != 0) if(acc[k] < 0) acc[k] -= Pt; else acc[k] += Pt;}staticvoidprogressiveacinc(Header *h, int comp, int Al){ int Ns, i, z, k, Ss, Se, Ta, **ac, H, V; int ri, mcu, nacross, ndown, nhor, nver, eobrun, nzeros, pending, x, y, tmcu, blockno, q, nmcu; Huffman *acht; int *qt, rrrr, ssss, *acc, rs; uchar *ss; ss = h->ss; Ns = ss[0]; if(Ns != 1) jpgerror(h, "ReadJPG: illegal Ns>1 in progressive AC scan"); Ss = ss[1+2]; Se = ss[2+2]; H = h->comp[comp].H; V = h->comp[comp].V; nacross = h->nacross*H; ndown = h->ndown*V; q = 8*h->Hmax/H; nhor = (h->X+q-1)/q; q = 8*h->Vmax/V; nver = (h->Y+q-1)/q; /* initialize data structures */ h->cnt = 0; h->sr = 0; h->peek = -1; nibbles(ss[1+1], &z, &Ta); /* z is thrown away */ ri = h->ri; eobrun = 0; ac = h->accoeff[comp]; acht = &h->acht[Ta]; qt = h->qt[h->comp[comp].Tq]; nmcu = nacross*ndown; mcu = 0; pending = 0; nzeros = -1; for(y=0; y<nver; y++){ for(x=0; x<nhor; x++){ /* Figure G-7 */ /* arrange blockno to be in same sequence as original scan calculation. */ tmcu = x/H + (nacross/H)*(y/V); blockno = tmcu*H*V + H*(y%V) + x%H; acc = ac[blockno]; if(eobrun > 0){ if(nzeros > 0) jpgerror(h, "ReadJPG: zeros pending at block start"); for(k=Ss; k<=Se; k++) increment(h, acc, k, qt[k]<<Al); --eobrun; continue; } for(k=Ss; k<=Se; ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -