示例#1
2
bool CxImageJPG::DecodeExif(CxFile * hFile)
{
	long pos=hFile->Tell();
	CxExifInfo exif(&m_exifinfo);
	exif.DecodeExif(hFile);
	hFile->Seek(pos,SEEK_SET);
	return exif.m_exifinfo->IsExif;
}
示例#2
0
bool ReadJPEGInfo(const char *filename, JPEG_INFO& info)
{
	EXIFINFO exinfo;
	Exif exif(&exinfo);
	FILE *fp;
	bool success = false;

	memset(&exinfo, 0, sizeof(exinfo));

	if ((fp = fopen(filename, "rb")) != NULL) {
		if (exif.DecodeExif(fp)) {
			info.CameraMake  = exinfo.CameraMake;
			info.CameraModel = exinfo.CameraModel;
			info.Width  	 = exinfo.Width;
			info.Height 	 = exinfo.Height;
			info.Orientation = exinfo.Orientation;
			info.bDateValid  = false;
			info.Comments    = exinfo.Comments;

			AString str = exinfo.DateTime;

			if (str.Valid()) {
				//printf("File '%s' has date '%s'\n", filename, str.str());

				str.Replace(":/-.", "    ");
				
				ADateTime& dt = info.DateTime;
				uint_t word = 0;
				
				uint16_t year   = str.Word(word++);
				uint8_t  month  = str.Word(word++);
				uint8_t  day    = str.Word(word++);
				uint8_t  hour   = str.Word(word++);
				uint8_t  minute = str.Word(word++);
				uint8_t  second = str.Word(word++);

				if ((year >= 1980) && RANGE(month, 1, 12) && RANGE(day, 1, 31) && (hour <= 23) && (minute <= 59) && (second <= 61)) {
					dt.Set(day, month, year, hour, minute, second);
					
					info.bDateValid = true;
				}
			}

			success = true;
		}
		
		fclose(fp);
	}

	return success;
}
示例#3
0
bool CxImageJPG::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type)
{
  CxIOFile file;
  if (!file.Open(filename, _T("rb"))) return false;
	CxExifInfo exif(&info.ExifInfo);
	exif.DecodeExif(&file);
  if (info.ExifInfo.IsExif && info.ExifInfo.ThumbnailPointer && info.ExifInfo.ThumbnailSize > 0)
  { // have a thumbnail - check whether it needs rotating or resizing
    // TODO: Write a fast routine to read the jpeg header to get the width and height
    CxImage image(info.ExifInfo.ThumbnailPointer, info.ExifInfo.ThumbnailSize, CXIMAGE_FORMAT_JPG);
    if (image.IsValid())
    {
      if (image.GetWidth() > 256 || image.GetHeight() > 256)
      { // resize the image
//        float amount = 256.0f / max(image.GetWidth(), image.GetHeight());
//        image.Resample((int32_t)(image.GetWidth() * amount), (int32_t)(image.GetHeight() * amount), 0);
      }
#if CXIMAGE_SUPPORT_TRANSFORMATION
      if (info.ExifInfo.Orientation != 1)
        image.RotateExif(info.ExifInfo.Orientation);
#endif
#if CXIMAGE_SUPPORT_ENCODE
      return image.Save(outname, CXIMAGE_FORMAT_JPG);
#endif
    }
    // nice and fast, but we can't resize :(
    /*
    FILE *hFileWrite;
    if ((hFileWrite=fopen(outname, "wb")) != NULL)
    {
      fwrite(m_exifinfo.ThumbnailPointer, m_exifinfo.ThumbnailSize, 1, hFileWrite);
      fclose(hFileWrite);
      return true;
    }*/
  }
  return false;
}
示例#4
0
文件: png.cpp 项目: pgarner/eximp
void PNG::dump()
{
    // Text chunks
    png_textp textp = 0;
    int ntext = 0;
    png_get_text(mData, mInfo, &textp, &ntext);
    var text;
    for (int i=0; i<ntext; i++)
        text[textp[i].key] = textp[i].text;
    std::cout << "Text: " << text << std::endl;

    // EXIF
    // The library reports "png_get_eXIf does not work; use png_get_eXIf_1"
    png_bytep exif_data = 0;
    png_uint_32 num_exif = 0;
    png_uint_32 pngRet = png_get_eXIf_1(mData, mInfo, &num_exif, &exif_data);
    if (pngRet)
    {
        assert(exif_data);
        EXIF exif(exif_data, num_exif);
        exif.dump();
        std::cout << "EXIF date: " << exif.date() << std::endl;
    }
}
示例#5
0
AReader::Error ReaderJpeg::read( imageCache &cache, const uint8_t* data, unsigned length, QString format ) const{
	if( !can_read( data, length, format ) )
		return ERROR_TYPE_UNKNOWN;
	
	try{
		cache.set_info( 1 );
		JpegDecompress jpeg( data, length );
		jpeg.cinfo.client_data = &cache;
		
		//Save application data, we are interested in ICC profiles and EXIF metadata
		jpeg.saveMarker( ICC_META_TEST );
		jpeg.saveMarker( EXIF_META_TEST );
		/* READ EVERYTHING!
		jpeg_save_markers( &jpeg.cinfo, JPEG_COM, 0xFFFF );
		for( unsigned i=0; i<16; i++ )
			jpeg_save_markers( &jpeg.cinfo, JPEG_APP0+i, 0xFFFF );
		//*/
		
		//Read header and set-up image
		jpeg.readHeader();
		jpeg_start_decompress( &jpeg.cinfo );
		
		bool is_gray;
		switch( jpeg.cinfo.out_color_components ){
			case 1: is_gray = true; break;
			case 3: is_gray = false; break;
			default: return ERROR_UNSUPPORTED;
		}
		QImage frame( jpeg.cinfo.output_width, jpeg.cinfo.output_height, QImage::Format_RGB32 );
		
		//Read image
		auto buffer = std::make_unique<JSAMPLE[]>( jpeg.bytesPerLine() );
		JSAMPLE* arr[1] = { buffer.get() };
		while( jpeg.cinfo.output_scanline < jpeg.cinfo.output_height ){
			auto out = (QRgb*)frame.scanLine( jpeg.cinfo.output_scanline );
			jpeg_read_scanlines( &jpeg.cinfo, arr, 1 );
			
			if( is_gray )
				for( unsigned ix=0; ix<jpeg.cinfo.output_width; ix++ )
					out[ix] = qRgb( buffer[ix], buffer[ix], buffer[ix] );
			else
				for( unsigned ix=0; ix<jpeg.cinfo.output_width; ix++ )
					out[ix] = qRgb( buffer[ix*3+0], buffer[ix*3+1], buffer[ix*3+2] );
		}
		
		//Check all markers
		for( auto marker = jpeg.cinfo.marker_list; marker; marker = marker->next ){
			//Check for and read ICC profile
			if( ICC_META_TEST.validate( marker ) ){
				cache.set_profile( ColorProfile::fromMem(
						marker->data        + ICC_META_TEST.length
					,	marker->data_length - ICC_META_TEST.length
					) );
			}
			if( EXIF_META_TEST.validate( marker ) ){
				meta exif(
						marker->data        + EXIF_META_TEST.length
					,	marker->data_length - EXIF_META_TEST.length
					);
				
				cache.set_orientation( exif.get_orientation() );
				
				//Read thumbnail
				cache.thumbnail = exif.get_thumbnail();
				//TODO: We actually want to read this BEFORE the full image ;)
				
				//TODO: Actually do something with this info. Perhaps check for a profile as well!
			}
			/* Save data to file for debugging
			QFile f( "Jpeg marker " + QString::number(marker->marker-JPEG_APP0) + ".bin" );
			f.open( QIODevice::WriteOnly );
			f.write( (char*)marker->data, marker->data_length );
			//*/
		}
		jpeg_finish_decompress( &jpeg.cinfo );
		
		cache.add_frame( frame, 0 );
		
		//Cleanup and return
		cache.set_fully_loaded();
		return ERROR_NONE;
	}
	catch( int err_code ){
		switch( err_code ){
			case JERR_NO_SOI: return ERROR_TYPE_UNKNOWN;
			default: return ERROR_FILE_BROKEN;
		};
	}
}