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

📄 qgifimageformat.cpp

📁 qt-embedded-2.3.8.tar.gz源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}		right=QMAX( 0, left+width-1);		bottom=QMAX(0, top+height-1);		lcmap=!!(hold[9]&0x80);		interlace=!!(hold[9]&0x40);		//bool lcmsortflag=!!(hold[9]&0x20);		lncols=lcmap ? (2<<(hold[9]&0x7)) : 0;		if (lncols) {		    if ( localcmap )			delete [] localcmap;		    localcmap = new QRgb[lncols+1];		    localcmap[lncols] = Q_TRANSPARENT;		    ncols = lncols;		} else {		    ncols = gncols;		}		frame++;		if ( frame == 0 ) {		    if ( left || top || width!=swidth || height!=sheight ) {			// Not full-size image - erase with bg or transparent			if ( trans_index >= 0 ) {			    fillRect(img, 0, 0, swidth, sheight, color(trans_index));			    if (consumer) consumer->changed(QRect(0,0,swidth,sheight));			} else if ( bgcol>=0 ) {			    fillRect(img, 0, 0, swidth, sheight, color(bgcol));			    if (consumer) consumer->changed(QRect(0,0,swidth,sheight));			}		    }		}		if ( disposal == RestoreImage ) {		    int l = QMIN(swidth-1,left);		    int r = QMIN(swidth-1,right);		    int t = QMIN(sheight-1,top);		    int b = QMIN(sheight-1,bottom);		    int w = r-l+1;		    int h = b-t+1;		    if (backingstore.width() < w			|| backingstore.height() < h) {			// We just use the backing store as a byte array			backingstore.create( QMAX(backingstore.width(), w),					     QMAX(backingstore.height(), h),					     32);			memset( img.bits(), 0, img.numBytes() );		    }		    for (int ln=0; ln<h; ln++) {			memcpy(backingstore.scanLine(ln),			       line[t+ln]+l, w*sizeof(QRgb));		    }		}		count=0;		if (lcmap) {		    ccount=0;		    state=LocalColorMap;		} else {		    state=TableImageLZWSize;		}		x = left;		y = top;		accum = 0;		bitcount = 0;		sp = stack;		needfirst = FALSE;		out_of_bounds = FALSE;	    }	    break;	  case TableImageLZWSize: {	    lzwsize=ch;	    if ( lzwsize > max_lzw_bits ) {		state=Error;	    } else {		code_size=lzwsize+1;		clear_code=1<<lzwsize;		end_code=clear_code+1;		max_code_size=2*clear_code;		max_code=clear_code+2;		int i;		for (i=0; i<clear_code && i<(1<<max_lzw_bits); i++) {		    table[0][i]=0;		    table[1][i]=i;		}		for (i=clear_code; i<(1<<max_lzw_bits); i++) {		    table[0][i]=table[1][i]=0;		}		state=ImageDataBlockSize;	    }	    count=0;	    break;	  } case ImageDataBlockSize:	    expectcount=ch;	    if (expectcount) {		state=ImageDataBlock;	    } else {		if (consumer) {		    consumer->frameDone();		    digress = TRUE;		}		state=Introducer;	    }	    break;	  case ImageDataBlock:	    count++;	    accum|=(ch<<bitcount);	    bitcount+=8;	    while (bitcount>=code_size && state==ImageDataBlock) {		int code=accum&((1<<code_size)-1);		bitcount-=code_size;		accum>>=code_size;		if (code==clear_code) {		    if (!needfirst) {			int i;			code_size=lzwsize+1;			max_code_size=2*clear_code;			max_code=clear_code+2;			for (i=0; i<clear_code; i++) {			    table[0][i]=0;			    table[1][i]=i;			}			for (i=clear_code; i<(1<<max_lzw_bits); i++) {			    table[0][i]=table[1][i]=0;			}		    }		    needfirst=TRUE;		} else if (code==end_code) {		    bitcount = -32768;		    // Left the block end arrive		} else {		    if (needfirst) {			firstcode=oldcode=code;			if (!out_of_bounds && line && firstcode!=trans_index)			    line[y][x] = color(firstcode);			x++;			if (x>=swidth) out_of_bounds = TRUE;			needfirst=FALSE;			if (x>right) {			    x=left;			    if (out_of_bounds)				out_of_bounds = left>=swidth || y>=sheight;			    nextY(img,consumer);			}		    } else {			incode=code;			if (code>=max_code) {			    *sp++=firstcode;			    code=oldcode;			}			while (code>=clear_code) {			    *sp++=table[1][code];			    if (code==table[0][code]) {				state=Error;				break;			    }			    if (sp-stack>=(1<<(max_lzw_bits))*2) {				state=Error;				break;			    }			    code=table[0][code];			}			*sp++=firstcode=table[1][code];			code=max_code;			if (code<(1<<max_lzw_bits)) {			    table[0][code]=oldcode;			    table[1][code]=firstcode;			    max_code++;			    if ((max_code>=max_code_size)			     && (max_code_size<(1<<max_lzw_bits)))			    {				max_code_size*=2;				code_size++;			    }			}			oldcode=incode;			while (sp>stack) {			    --sp;			    if (!out_of_bounds && *sp!=trans_index)				line[y][x] = color(*sp);			    x++;			    if (x>=swidth) out_of_bounds = TRUE;			    if (x>right) {				x=left;				if (out_of_bounds)				    out_of_bounds = left>=swidth || y>=sheight;				nextY(img,consumer);			    }			}		    }		}	    }	    if (count==expectcount) {		count=0;		state=ImageDataBlockSize;	    }	    break;	  case ExtensionLabel:	    switch (ch) {	    case 0xf9:		state=GraphicControlExtension;		break;	    case 0xff:		state=ApplicationExtension;		break;#if 0	    case 0xfe:		state=CommentExtension;		break;	    case 0x01:		break;#endif	    default:		state=SkipBlockSize;	    }	    count=0;	    break;	  case ApplicationExtension:	    if (count<11) hold[count]=ch;	    count++;	    if (count==hold[0]+1) {		if (qstrncmp((char*)(hold+1), "NETSCAPE", 8)==0) {		    // Looping extension		    state=NetscapeExtensionBlockSize;		} else {		    state=SkipBlockSize;		}		count=0;	    }	    break;	  case NetscapeExtensionBlockSize:	    expectcount=ch;	    count=0;	    if (expectcount) state=NetscapeExtensionBlock;	    else state=Introducer;	    break;	  case NetscapeExtensionBlock:	    if (count<3) hold[count]=ch;	    count++;	    if (count==expectcount) {		int loop = hold[0]+hold[1]*256;		// Why if the extension here, if it is supposed to only		// play through once?  We assume that the creator meant		// 0, which is infinite.		if (loop == 1) loop = 0;		if (consumer) consumer->setLooping(loop);		state=SkipBlockSize; // Ignore further blocks	    }	    break;	  case GraphicControlExtension:	    if (count<5) hold[count]=ch;	    count++;	    if (count==hold[0]+1) {		disposePrevious( img, consumer );		disposal=Disposal((hold[1]>>2)&0x7);		//UNUSED: waitforuser=!!((hold[1]>>1)&0x1);		int delay=count>3 ? LM(hold[2], hold[3]) : 1;		// IE and mozilla use a minimum delay of 10. With the minumum delay of 10		// we are compatible to them and avoid huge loads on the app and xserver.		if ( delay < 10 )		    delay = 10;		bool havetrans=hold[1]&0x1; 		trans_index = havetrans ? hold[4] : -1;		if (consumer) consumer->setFramePeriod(delay*10);		count=0;		state=SkipBlockSize;	    }	    break;	  case SkipBlockSize:	    expectcount=ch;	    count=0;	    if (expectcount) state=SkipBlock;	    else state=Introducer;	    break;	  case SkipBlock:	    count++;	    if (count==expectcount) state=SkipBlockSize;	    break;	  case Done:	    digress=TRUE;	    /* Netscape ignores the junk, so we do too.	    length++; // Unget	    state=Error; // More calls to this is an error	    */	    break;	  case Error:	    return -1; // Called again after done.	}    }    return initial-length;}void QGIFFormat::fillRect(QImage& img, int col, int row, int w, int h, QRgb color){    if (w>0) {	QRgb** line = (QRgb **)img.jumpTable() + row;	for (int j=0; j<h; j++) {	    for ( int i=0; i<w; i++ ) {		*(line[j]+col+i) = color;	    }	}    }}void QGIFFormat::nextY(QImage& img, QImageConsumer* consumer){    int my;    switch (interlace) {      case 0:	// Non-interlaced	if (consumer && !out_of_bounds)	    consumer->changed(QRect(left, y, right-left+1, 1));	y++;	break;      case 1:	{	    int i;	    my = QMIN(7, bottom-y);	    if ( trans_index < 0 ) // Don't dup with transparency		for (i=1; i<=my; i++)		    memcpy(img.scanLine(y+i)+left, img.scanLine(y)+left,			(right-left+1)*sizeof(QRgb));	    if (consumer && !out_of_bounds)		consumer->changed(QRect(left, y, right-left+1, my+1));	    y+=8;	    if (y>bottom) {		interlace++; y=top+4;		if (y > bottom) { // for really broken GIFs with bottom < 5		    interlace=2;		    y = top + 2;		    if (y > bottom) { // for really broken GIF with bottom < 3			interlace = 0;			y = top + 1;		    }		}	    }	} break;      case 2:	{	    int i;	    my = QMIN(3, bottom-y);	    if ( trans_index < 0 ) // Don't dup with transparency		for (i=1; i<=my; i++)		    memcpy(img.scanLine(y+i)+left, img.scanLine(y)+left,			(right-left+1)*sizeof(QRgb));	    if (consumer && !out_of_bounds)		consumer->changed(QRect(left, y, right-left+1, my+1));	    y+=8;	    if (y>bottom) {		interlace++; y=top+2;		if (y > bottom) { // for really broken GIF with bottom < 3		    interlace = 3;		    y = top + 1;		}	    }	} break;      case 3:	{	    int i;	    my = QMIN(1, bottom-y);	    if ( trans_index < 0 ) // Don't dup with transparency		for (i=1; i<=my; i++)		    memcpy(img.scanLine(y+i)+left, img.scanLine(y)+left,			(right-left+1)*sizeof(QRgb));	    if (consumer && !out_of_bounds)		consumer->changed(QRect(left, y, right-left+1, my+1));	    y+=4;	    if (y>bottom) { interlace++; y=top+1; }	} break;      case 4:	if (consumer && !out_of_bounds)	    consumer->changed(QRect(left, y, right-left+1, 1));	y+=2;    }    // Consume bogus extra lines    if (y >= sheight) out_of_bounds=TRUE; //y=bottom;}QRgb QGIFFormat::color( uchar index ) const{    if ( index == trans_index || index > ncols )	return Q_TRANSPARENT;    QRgb *map = lcmap ? localcmap : globalcmap;    return map ? map[index] : 0;}#endif // QT_BUILTIN_GIF_READER#endif // QT_NO_ASYNC_IMAGE_IO

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -