⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readjpg.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
				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 + -