예제 #1
0
void ScImgDataLoader_JPEG::loadEmbeddedProfile(const QString& fn, int /*page*/)
{
	m_embeddedProfile.resize(0);
	m_profileComponents = 0;
	if (!QFile::exists(fn))
		return;
	struct jpeg_decompress_struct cinfo;
	struct my_error_mgr         jerr;
	FILE     *infile;
	cinfo.err = jpeg_std_error (&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	infile = NULL;
	if (setjmp (jerr.setjmp_buffer))
	{
		jpeg_destroy_decompress (&cinfo);
		if (infile)
			fclose (infile);
		return;
	}
	jpeg_create_decompress (&cinfo);
	if ((infile = fopen (fn.toLocal8Bit(), "rb")) == NULL)
		return;
	jpeg_stdio_src(&cinfo, infile);
	jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
	jpeg_read_header(&cinfo, true);
	//jpeg_start_decompress(&cinfo);
	unsigned int EmbedLen = 0;
	unsigned char* EmbedBuffer;
	if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen))
	{
		cmsHPROFILE prof = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
		if (prof)
		{
			if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
				m_profileComponents = 3;
			if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
				m_profileComponents = 4;
			if (static_cast<int>(cmsGetColorSpace(prof)) == icSigGrayData)
				m_profileComponents = 1;
			m_embeddedProfile = QByteArray((const char*) EmbedBuffer, EmbedLen);
		}
		cmsCloseProfile(prof);
		free(EmbedBuffer);
	}
	//(void) jpeg_finish_decompress(&cinfo);
	fclose (infile);
	jpeg_destroy_decompress (&cinfo);
}
예제 #2
0
void ScImgDataLoader_JPEG::loadEmbeddedProfile(const QString& fn, int /*page*/)
{
	m_embeddedProfile.resize(0);
	m_profileComponents = 0;
	if (!QFile::exists(fn))
		return;
	struct jpeg_decompress_struct cinfo;
	struct my_error_mgr         jerr;
	FILE     *infile;
	cinfo.err = jpeg_std_error (&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	infile = NULL;
	if (setjmp (jerr.setjmp_buffer))
	{
		jpeg_destroy_decompress (&cinfo);
		if (infile)
			fclose (infile);
		return;
	}
	jpeg_create_decompress (&cinfo);
	if ((infile = fopen (fn.toLocal8Bit(), "rb")) == NULL)
		return;
	jpeg_stdio_src(&cinfo, infile);
	jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
	jpeg_read_header(&cinfo, true);
	unsigned int EmbedLen = 0;
	unsigned char* EmbedBuffer;
	if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen))
	{
		QByteArray profArray = QByteArray((const char*) EmbedBuffer, EmbedLen);
		ScColorProfile prof  = ScColorMgmtEngine::openProfileFromMem(profArray);
		if (prof)
		{
			if (prof.colorSpace() == ColorSpace_Rgb)
				m_profileComponents = 3;
			if (prof.colorSpace() == ColorSpace_Cmyk)
				m_profileComponents = 4;
			if (prof.colorSpace() == ColorSpace_Gray)
				m_profileComponents = 1;
			m_embeddedProfile = profArray;
		}
		free(EmbedBuffer);
	}
	fclose (infile);
	jpeg_destroy_decompress (&cinfo);
}
예제 #3
0
bool ScImgDataLoader_JPEG::loadPicture(const QString& fn, int /*page*/, int res, bool thumbnail)
{
	bool isCMYK = false;
	bool fromPS = false;
	float xres = 72.0, yres = 72.0;
	if (!QFile::exists(fn))
		return false;
	ExifData ExifInf;
	struct jpeg_decompress_struct cinfo;
	struct my_error_mgr         jerr;
	FILE     *infile;
	cinfo.err = jpeg_std_error (&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	infile = NULL;

	initialize();
	m_imageInfoRecord.type = ImageTypeJPG;
	m_imageInfoRecord.exifInfo.thumbnail = QImage();
	if (setjmp (jerr.setjmp_buffer))
	{
		jpeg_destroy_decompress (&cinfo);
		if (infile)
			fclose (infile);
		return false;
	}
	jpeg_create_decompress (&cinfo);
	if ((infile = fopen (fn.toLocal8Bit(), "rb")) == NULL)
		return false;
	jpeg_stdio_src(&cinfo, infile);
	jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
	jpeg_save_markers(&cinfo, PHOTOSHOP_MARKER, 0xFFFF);
	jpeg_read_header(&cinfo, true);
	jpeg_start_decompress(&cinfo);
	bool exi = ExifInf.scan(fn);
	if ((exi) && (ExifInf.exifDataValid))
	{
		if (cinfo.output_components == 4)
			m_imageInfoRecord.colorspace = ColorSpaceCMYK;
		else if (cinfo.output_components == 3)
			m_imageInfoRecord.colorspace = ColorSpaceRGB;
		else if (cinfo.output_components == 1)
			m_imageInfoRecord.colorspace = ColorSpaceGray;
		if ((!ExifInf.Thumbnail.isNull()) && thumbnail)
		{
			m_image = ExifInf.getThumbnail();
			m_imageInfoRecord.exifInfo.thumbnail = ExifInf.getThumbnail();
			if (cinfo.output_components == 4)
			{
				QRgb *s;
				unsigned char cc, cm, cy, ck;
				for( int yit=0; yit < m_image.height(); ++yit )
				{
					s = (QRgb*)(m_image.scanLine( yit ));
					for(int xit=0; xit < m_image.width(); ++xit )
					{
						cc = 255 - qRed(*s);
						cm = 255 - qGreen(*s);
						cy = 255 - qBlue(*s);
						ck = qMin(qMin(cc, cm), cy);
						*s = qRgba(cc-ck,cm-ck,cy-ck,ck);
						s++;
					}
				}
			}
		}
		else
			m_imageInfoRecord.exifInfo.thumbnail = QImage();
		m_imageInfoRecord.exifInfo.cameraName = ExifInf.getCameraModel();
		m_imageInfoRecord.exifInfo.cameraVendor = ExifInf.getCameraMake();
		m_imageInfoRecord.exifInfo.comment = ExifInf.getComment();
		m_imageInfoRecord.exifInfo.width = ExifInf.getWidth();
		m_imageInfoRecord.exifInfo.height = ExifInf.getHeight();
		m_imageInfoRecord.exifInfo.userComment = ExifInf.getUserComment();
		m_imageInfoRecord.exifInfo.dateTime = ExifInf.getDateTime();
		m_imageInfoRecord.exifInfo.ApertureFNumber = ExifInf.getApertureFNumber();
		m_imageInfoRecord.exifInfo.ExposureTime = ExifInf.getExposureTime();
		m_imageInfoRecord.exifInfo.ISOequivalent = ExifInf.getISOequivalent();
		m_imageInfoRecord.exifDataValid = true;
		if (cinfo.density_unit == 0)
		{
			xres = 72;
			yres = 72;
		}
		else if ( cinfo.density_unit == 1 )
		{
			xres = cinfo.X_density;
			yres = cinfo.Y_density;
		}
		else if ( cinfo.density_unit == 2 )
		{
			xres = cinfo.X_density * 2.54;
			yres = cinfo.Y_density * 2.54;
		}
		if( xres <= 1.0 || yres <= 1.0 || xres > 3000.0 || yres > 3000.0 )
		{
			xres = yres = 72.0;
			QFileInfo qfi(fn);
			m_message = QObject::tr("%1 may be corrupted : missing or wrong resolution tags").arg(qfi.fileName());
			m_msgType = warningMsg;
		}
		m_imageInfoRecord.xres = qRound(xres);
		m_imageInfoRecord.yres = qRound(yres);
		m_imageInfoRecord.progressive = jpeg_has_multiple_scans(&cinfo);
		if ((!ExifInf.Thumbnail.isNull()) && thumbnail)
		{
			jpeg_destroy_decompress(&cinfo);
			fclose(infile);
			return true;
		}
	}
	else
		m_imageInfoRecord.exifDataValid = false;
	m_imageInfoRecord.exifInfo.thumbnail = QImage();
	unsigned int EmbedLen = 0;
	unsigned char* EmbedBuffer;
	if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen))
	{
		QByteArray profArray = QByteArray((const char*) EmbedBuffer, EmbedLen);
		ScColorProfile prof = ScColorMgmtEngine::openProfileFromMem(profArray);
		m_embeddedProfile   = profArray;
		m_imageInfoRecord.profileName = prof.productDescription();
		m_imageInfoRecord.isEmbedded  = true;
		free(EmbedBuffer);
	}
	else
	{
		m_imageInfoRecord.isEmbedded = false;
		m_imageInfoRecord.profileName = "";
	}
	unsigned int PhotoshopLen = 0;
	unsigned char * PhotoshopBuffer;
	if (cinfo.density_unit == 0)
	{
		xres = 72;
		yres = 72;
		m_image.setDotsPerMeterX(2834);
		m_image.setDotsPerMeterY(2834);
	}
	else if ( cinfo.density_unit == 1 )
	{
		xres = cinfo.X_density;
		yres = cinfo.Y_density;
		m_image.setDotsPerMeterX( int(100. * cinfo.X_density / 2.54) );
		m_image.setDotsPerMeterY( int(100. * cinfo.Y_density / 2.54) );
	}
	else if ( cinfo.density_unit == 2 )
	{
		xres = cinfo.X_density * 2.54;
		yres = cinfo.Y_density * 2.54;
		m_image.setDotsPerMeterX( int(100. * cinfo.X_density) );
		m_image.setDotsPerMeterY( int(100. * cinfo.Y_density) );
	}
	if( xres <= 1.0 || yres <= 1.0 || xres > 3000.0 || yres > 3000.0 )
	{
		xres = yres = 72.0;
		m_image.setDotsPerMeterX(2834);
		m_image.setDotsPerMeterY(2834);
		QFileInfo qfi(fn);
		m_message = QObject::tr("%1 may be corrupted : missing or wrong resolution tags").arg(qfi.fileName());
		m_msgType = warningMsg;
	}
	m_imageInfoRecord.xres = qRound(xres);
	m_imageInfoRecord.yres = qRound(yres);
	if (cinfo.output_components == 4)
	{
		isCMYK = true;
		m_imageInfoRecord.colorspace = ColorSpaceCMYK;
	}
	else if (cinfo.output_components == 3)
		m_imageInfoRecord.colorspace = ColorSpaceRGB;
	else if (cinfo.output_components == 1)
		m_imageInfoRecord.colorspace = ColorSpaceGray;
	m_imageInfoRecord.progressive = jpeg_has_multiple_scans(&cinfo);

	if (read_jpeg_marker(PHOTOSHOP_MARKER,&cinfo, &PhotoshopBuffer, &PhotoshopLen) )
	{
		if (PhotoshopLen != 0)
		{
			bool savEx = m_imageInfoRecord.exifDataValid;
			QByteArray arrayPhot(PhotoshopLen, ' ');
			arrayPhot = QByteArray::fromRawData((const char*)PhotoshopBuffer,PhotoshopLen);
			QDataStream strPhot(&arrayPhot,QIODevice::ReadOnly);
			strPhot.setByteOrder( QDataStream::BigEndian );
			PSDHeader fakeHeader;
			fakeHeader.width = cinfo.output_width;
			fakeHeader.height = cinfo.output_height;
			if (cinfo.output_components == 4)
				m_imageInfoRecord.colorspace = ColorSpaceCMYK;
			else if (cinfo.output_components == 3)
				m_imageInfoRecord.colorspace = ColorSpaceRGB;
			else if (cinfo.output_components == 1)
				m_imageInfoRecord.colorspace = ColorSpaceGray;
			m_imageInfoRecord.progressive = jpeg_has_multiple_scans(&cinfo);
			parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
			// Photoshop resolution is more accurate than jpeg header resolution
			xres = m_imageInfoRecord.xres;
			yres = m_imageInfoRecord.yres;
			m_image.setDotsPerMeterX( int(100. * m_imageInfoRecord.xres / 2.54) );
			m_image.setDotsPerMeterY( int(100. * m_imageInfoRecord.yres / 2.54) );
			if( xres <= 1.0 || yres <= 1.0 || xres > 3000.0 || yres > 3000.0 )
			{
				xres = yres = 72.0;
				m_imageInfoRecord.xres = qRound(xres);
				m_imageInfoRecord.yres = qRound(yres);
				m_image.setDotsPerMeterX(2834);
				m_image.setDotsPerMeterY(2834);
				QFileInfo qfi(fn);
				m_message = QObject::tr("%1 may be corrupted : missing or wrong resolution tags").arg(qfi.fileName());
				m_msgType = warningMsg;
			}
			if (m_imageInfoRecord.exifDataValid && !m_imageInfoRecord.exifInfo.thumbnail.isNull() && thumbnail)
			{
				m_image = QImage(m_imageInfoRecord.exifInfo.width, m_imageInfoRecord.exifInfo.height, QImage::Format_ARGB32 );
				m_imageInfoRecord.exifInfo.width = cinfo.output_width;
				m_imageInfoRecord.exifInfo.height = cinfo.output_height;
				if (cinfo.output_components == 4)
				{
					QRgb *d;
					QRgb *s;
					unsigned char cc, cm, cy, ck;
					for( int yit=0; yit < m_image.height(); ++yit )
					{
						d = (QRgb*)(m_image.scanLine( yit ));
						s = (QRgb*)(m_imageInfoRecord.exifInfo.thumbnail.scanLine( yit ));
						for(int xit=0; xit < m_image.width(); ++xit )
						{
							cc = 255 - qRed(*s);
							cm = 255 - qGreen(*s);
							cy = 255 - qBlue(*s);
							ck = qMin(qMin(cc, cm), cy);
							*d = qRgba(cc-ck,cm-ck,cy-ck,ck);
							s++;
							d++;
						}
					}
				}
				else
					m_image = m_imageInfoRecord.exifInfo.thumbnail.copy();
			}
			m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0?true:false; // The only interest is vectormask
			arrayPhot.clear();
			free( PhotoshopBuffer );
			if (m_imageInfoRecord.exifDataValid && !m_imageInfoRecord.exifInfo.thumbnail.isNull() && thumbnail)
			{
				jpeg_destroy_decompress(&cinfo);
				fclose(infile);
				return true;
			}
			m_imageInfoRecord.exifInfo.thumbnail = QImage();
			m_imageInfoRecord.exifDataValid = savEx;
			fromPS = true;
		}
	}
	if ( cinfo.output_components == 3 || cinfo.output_components == 4)
		m_image = QImage( cinfo.output_width, cinfo.output_height, QImage::Format_ARGB32 );
	else if ( cinfo.output_components == 1 )
	{
		m_image = QImage( cinfo.output_width, cinfo.output_height, QImage::Format_Indexed8 );
		m_image.setNumColors(256);
		for (int i=0; i<256; i++)
			m_image.setColor(i, qRgb(i,i,i));
	}
	if (!m_image.isNull())
	{
		uchar* data = m_image.bits();
		int bpl = m_image.bytesPerLine();
		while (cinfo.output_scanline < cinfo.output_height)
		{
			uchar *d = data + cinfo.output_scanline * bpl;
			(void) jpeg_read_scanlines(&cinfo, &d, 1);
		}
		if ( cinfo.output_components == 3 )
		{
			uchar *in;
			QRgb *out;
			for (uint j=0; j<cinfo.output_height; j++)
			{
				in = m_image.scanLine(j) + cinfo.output_width * 3;
				out = (QRgb*) m_image.scanLine(j);
				for (uint i=cinfo.output_width; i--; )
				{
					in -= 3;
					out[i] = qRgb(in[0], in[1], in[2]);
				}
			}
		}
		if ( cinfo.output_components == 4 )
		{
			int method = 0;
			if (cinfo.jpeg_color_space == JCS_YCCK)
				method = 1;
			else if (fromPS)
			{
				if ((cinfo.jpeg_color_space == JCS_CMYK) && (cinfo.saw_Adobe_marker) && (cinfo.Adobe_transform == 0))
					method = 2;
			}
			else if ((cinfo.jpeg_color_space == JCS_CMYK) && (cinfo.saw_Adobe_marker))
				method = 1;
			QRgb *ptr;
			unsigned char c, m, y ,k;
			unsigned char *p;
			for (int i = 0; i < m_image.height(); i++)
			{
				ptr = (QRgb*)  m_image.scanLine(i);
				if (method == 1)
				{
					for (int j = 0; j <  m_image.width(); j++)
					{
						p = (unsigned char *) ptr;
						c = p[0];
						m = p[1];
						y =  p[2];
						k =  p[3];
						*ptr = qRgba(255 - c, 255 - m, 255 - y, 255 - k);
						ptr++;
					}
				}
				else if (method == 2)
				{
					for (int j = 0; j <  m_image.width(); j++)
					{
						p = (unsigned char *) ptr;
						c = p[0];
						m = p[1];
						y =  p[2];
						k =  p[3];
						*ptr = qRgba(255 - c, 255 - m, 255 - y, k);
						ptr++;
					}
				}
				else
				{
					for (int j = 0; j <  m_image.width(); j++)
					{
						p = (unsigned char *) ptr;
						c = p[0];
						m = p[1];
						y =  p[2];
						k =  p[3];
						*ptr = qRgba(y, m, c, k);
						ptr++;
					}
				}
			}
			isCMYK = true;
		}
		else
			isCMYK = false;
		if ( cinfo.output_components == 1 )
		{
			QImage tmpImg = m_image.convertToFormat(QImage::Format_ARGB32);
			m_image = QImage( cinfo.output_width, cinfo.output_height, QImage::Format_ARGB32 );
			QRgb *s;
			QRgb *d;
			for( int yi=0; yi < tmpImg.height(); ++yi )
			{
				s = (QRgb*)(tmpImg.scanLine( yi ));
				d = (QRgb*)(m_image.scanLine( yi ));
				for(int xi=0; xi < tmpImg.width(); ++xi )
				{
					(*d) = (*s);
					s++;
					d++;
				}
			}
		}
	}
	(void) jpeg_finish_decompress(&cinfo);
	fclose (infile);
	jpeg_destroy_decompress (&cinfo);
	m_imageInfoRecord.layerInfo.clear();
	m_imageInfoRecord.BBoxX = 0;
	m_imageInfoRecord.BBoxH = m_image.height();
	return (!m_image.isNull());
}