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

📄 jpeg.cpp

📁 一种效率高
💻 CPP
字号:
//////////////////////////////////////////////////////// Transparent support for JPEG files in Qt Pixmaps,// using IJG JPEG library.//// Sirtaj Kang, Oct 1996.//// $Id: jpeg.cpp,v 1.1 2003/09/08 19:42:14 jasonk Exp $#ifdef HAVE_CONFIG_H#include"config.h"#endif#ifdef HAVE_LIBJPEG#include<stdio.h>#include<assert.h>#include<sys/types.h>#include"qimage.h"#include"qdstream.h"#include"qcolor.h"#include"qpixmap.h"#include"jpeg.h"//// Hack to fix INT16 redefinition problem//#define XMD_Htypedef short INT16;extern "C" {#include<jpeglib.h>}#undef XMD_H//////// Plug-in source manager for IJG JPEG compression/decompression library//// // Source control structure.// typedef struct {  struct jpeg_source_mgr pub;   /* public fields */    QDataStream *infile;                /* Pointer to QIODevice object */      JOCTET * buffer;              /* start of buffer */        boolean start_of_file;        /* have we gotten any data yet? */	} qimageio_jpeg_source_mgr;	void qimageio_jpeg_src(j_decompress_ptr cinfo, QDataStream *image);	//	// Source manager file request plug-in methods.	//	void qimageio_init_source(j_decompress_ptr cinfo);	boolean qimageio_fill_input_buffer(j_decompress_ptr cinfo);	void qimageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes);	void qimageio_term_source(j_decompress_ptr cinfo);	// Buffer for file reads (max bytes)	// ?? Is this good enough? Bigger, perhaps?	#define INPUT_BUFFER_SIZE 4096///////////////////////// No JPEG save support yet//void kimgio_jpeg_write(QImageIO *){    fprintf(stderr, "JPEG saving unimplemented.\n");    return;}/////////////// Plug-in to read files from JPEG into QImage//void kimgio_jpeg_read(QImageIO * iio){    QIODevice *d = iio->ioDevice();    QImage image;    QDataStream s(d);    JSAMPROW buffer[1];    unsigned int *ui_row;    unsigned char *uc_row, *uc_row_index;    unsigned int depth, col;    unsigned char r,g,b;    // We need to know if the display can handle 32-bit images    depth = QPixmap::defaultDepth();    // Init jpeg decompression structures    struct jpeg_decompress_struct cinfo;    struct jpeg_error_mgr jerr;    cinfo.err = jpeg_std_error(&jerr);    jpeg_create_decompress(&cinfo);    qimageio_jpeg_src(&cinfo, &s);    if( jpeg_read_header(&cinfo, (boolean) FALSE ) 		!= JPEG_HEADER_OK ) {	return; // Header error    }    // If we're in an 8bit display, we want a colourmap.    if ((depth < 32) && (cinfo.out_color_space == JCS_RGB)) {	cinfo.quantize_colors = (boolean) TRUE;	cinfo.dither_mode = JDITHER_ORDERED;    }    jpeg_start_decompress(&cinfo);    if (cinfo.quantize_colors == TRUE) {	image.create(cinfo.output_width, cinfo.output_height,		     8, cinfo.actual_number_of_colors,		      QImage::LittleEndian);	// Read colourmap	for ( col = 0; col < (unsigned)cinfo.actual_number_of_colors; 			col++ ) {	    image.setColor(col, qRgb(cinfo.colormap[0][col],				     cinfo.colormap[1][col],				     cinfo.colormap[2][col]));	}    } else if (cinfo.out_color_space == JCS_GRAYSCALE) {	image.create(cinfo.output_width, cinfo.output_height,		      8, 256, QImage::LittleEndian);	// Read colourmap	for (col = 0; col < 256; col++) {	    image.setColor(col, qRgb(col, col, col));	}    } else {	image.create(cinfo.output_width, cinfo.output_height, 32);    }    // Alloc one-row buffer for scanline     buffer[0] = new JSAMPLE[cinfo.output_width * cinfo.output_components];    //    // Perform decompression    //    // Decompress with colormap    if (cinfo.quantize_colors == TRUE || cinfo.out_color_space != JCS_RGB) {	while (cinfo.output_scanline < cinfo.output_height) {	    uc_row_index = image.scanLine(cinfo.output_scanline);	    uc_row = buffer[0];	    jpeg_read_scanlines(&cinfo, buffer, 1);	    for (col = 0; col < cinfo.output_width; col++)		*uc_row_index++ = *uc_row++;	}	// Decompress 24-bit    } else {	while (cinfo.output_scanline < cinfo.output_height) {	    ui_row = (unsigned int *)		image.scanLine(cinfo.output_scanline);	    uc_row = buffer[0];	    jpeg_read_scanlines(&cinfo, buffer, 1);	    for (col = 0; col < cinfo.output_width; col++) {		r = *uc_row++;		g = *uc_row++;		b = *uc_row++;		*ui_row++ = qRgb(r, g, b);            }	}    }    // Clean up JPEG structs    jpeg_finish_decompress(&cinfo);    jpeg_destroy_decompress(&cinfo);    // Bind new image to screen    iio->setImage(image);    iio->setStatus(0);}/////////    //    // JPEG plug in routines for QDataStream as input.    //// Registers stream routines for use by IJG JPEG libraryvoid qimageio_jpeg_src(j_decompress_ptr cinfo, QDataStream * image){    qimageio_jpeg_source_mgr *src;    // Set up buffer for the first time    if (cinfo->src == NULL) {	cinfo->src = (struct jpeg_source_mgr *)	    (*cinfo->mem->alloc_small)	    ((j_common_ptr) cinfo,	     JPOOL_PERMANENT,	     sizeof(qimageio_jpeg_source_mgr));	src = (qimageio_jpeg_source_mgr *) cinfo->src;	src->buffer = (JOCTET *)	    (*cinfo->mem->alloc_small)	    ((j_common_ptr) cinfo,	     JPOOL_PERMANENT,	     INPUT_BUFFER_SIZE * sizeof(JOCTET));    }    // Register methods    src = (qimageio_jpeg_source_mgr *) cinfo->src;    src->pub.init_source = qimageio_init_source;    src->pub.fill_input_buffer = qimageio_fill_input_buffer;    src->pub.skip_input_data = qimageio_skip_input_data;    src->pub.resync_to_restart = jpeg_resync_to_restart;    src->pub.term_source = qimageio_term_source;    // This is potentially dangerous, as it has chance of being    // misinterpreted. Saves effort, tho!    src->infile = image;    src->pub.bytes_in_buffer = 0;	/* forces fill_input_buffer on first read */    src->pub.next_input_byte = NULL;	/* until buffer loaded */}/////////    //    // Intializes data source    //void qimageio_init_source(j_decompress_ptr cinfo){    qimageio_jpeg_source_mgr *ptr = (qimageio_jpeg_source_mgr *) cinfo->src;    ptr->start_of_file = (boolean) TRUE;}				/////////    //    // Reads data from stream into JPEG working buffer    //boolean qimageio_fill_input_buffer(j_decompress_ptr cinfo){    qimageio_jpeg_source_mgr *ptr = (qimageio_jpeg_source_mgr *) cinfo->src;    size_t nbytes;    nbytes = ptr->infile->device()->readBlock((char *) (ptr->buffer),					      INPUT_BUFFER_SIZE);    if (nbytes <= 0) {	if (ptr->start_of_file) {	    fprintf(stderr, "error: file empty.\n");	    return (boolean) FALSE;	}	fprintf(stderr, "warning: premature EOF in file.\n");	/* Insert a fake EOI marker */	ptr->buffer[0] = (JOCTET) 0xFF;	ptr->buffer[1] = (JOCTET) JPEG_EOI;	nbytes = 2;    }    ptr->pub.next_input_byte = ptr->buffer;    ptr->pub.bytes_in_buffer = nbytes;    ptr->start_of_file = (boolean) FALSE;    return (boolean) TRUE;}//////////    //    // Jumps over large chunks of data. Can probably be done quicker. (fseek()    // style).void qimageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes){    qimageio_jpeg_source_mgr *ptr = (qimageio_jpeg_source_mgr *) cinfo->src;    if (num_bytes > 0) {	while (num_bytes > (long) ptr->pub.bytes_in_buffer) {	    num_bytes -= (long) ptr->pub.bytes_in_buffer;	    (void) qimageio_fill_input_buffer(cinfo);	} ptr->pub.next_input_byte += (size_t) num_bytes;	ptr->pub.bytes_in_buffer -= (size_t) num_bytes;    }}/////////    //    // Clean up. Doesn't really do anything, but required for compat.    //void qimageio_term_source(j_decompress_ptr){    return;}#endif

⌨️ 快捷键说明

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