Ejemplo n.º 1
0
void dng_info::ParseTag (dng_host &host,
						 dng_stream &stream,
						 dng_exif *exif,
						 dng_shared *shared,
						 dng_ifd *ifd,
						 uint32 parentCode,
						 uint32 tagCode,
						 uint32 tagType,
						 uint32 tagCount,
						 uint64 tagOffset,
						 int64 offsetDelta)
	{
	
	bool isSubIFD = parentCode >= tcFirstSubIFD &&
					parentCode <= tcLastSubIFD;
					  
	bool isMainIFD = (parentCode == 0 || isSubIFD) &&
					 ifd &&
					 ifd->fUsesNewSubFileType &&
			 		 ifd->fNewSubFileType == sfMainImage;
			 		 
	// Panasonic RAW format stores private tags using tag codes < 254 in
	// IFD 0.  Redirect the parsing of these tags into a logical
	// "PanasonicRAW" IFD.
	
	// Panasonic is starting to use some higher numbers also (280..283).
			 		 
	if (fMagic == 85 && parentCode == 0 && (tagCode < tcNewSubFileType ||
											(tagCode >= 280 && tagCode <= 283)))
		{
		
		parentCode = tcPanasonicRAW;
		
		ifd = NULL;
		
		}
	
	stream.SetReadPosition (tagOffset);
		
	if (ifd && ifd->ParseTag (stream,
						 	  parentCode,
						 	  tagCode,
						 	  tagType,
						 	  tagCount,
						 	  tagOffset))
		{
		
		return;
		
		}
		
	stream.SetReadPosition (tagOffset);
		
	if (exif && shared && exif->ParseTag (stream,
										  *shared,
										  parentCode,
										  isMainIFD,
										  tagCode,
										  tagType,
										  tagCount,
										  tagOffset))
		{
		
		return;
		
		}
		
	stream.SetReadPosition (tagOffset);
		
	if (shared && exif && shared->ParseTag (stream,
											*exif,
								    		parentCode,
								    		isMainIFD,
								    		tagCode,
								    		tagType,
								    		tagCount,
								    		tagOffset,
								    		offsetDelta))
		{
		
		return;
		
		}
		
	if (parentCode == tcOlympusMakerNote &&
		tagType == ttUndefined &&
		tagCount >= 14)
		{
		
		uint32 olympusMakerParent = 0;
		
		switch (tagCode)
			{
			
			case 8208:
				olympusMakerParent = tcOlympusMakerNote8208;
				break;
				
			case 8224:
				olympusMakerParent = tcOlympusMakerNote8224;
				break; 
		
			case 8240:
				olympusMakerParent = tcOlympusMakerNote8240;
				break; 
		
			case 8256:
				olympusMakerParent = tcOlympusMakerNote8256;
				break; 
		
			case 8272:
				olympusMakerParent = tcOlympusMakerNote8272;
				break; 
		
			case 12288:
				olympusMakerParent = tcOlympusMakerNote12288;
				break;
				
			default:
				break;
				
			}
			
		if (olympusMakerParent)
			{
			
			// Olympus made a mistake in some camera models in computing
			// the size of these sub-tags, so we fudge the count.
			
			if (ParseMakerNoteIFD (host,
								   stream,
							       stream.Length () - tagOffset,
				   	  		       tagOffset,
				   	  		       offsetDelta,
				   	  		       tagOffset,
				   	  		       stream.Length (),
				   	  		       olympusMakerParent))
				{
				
				return;
				
				}
			
			}
			
		}
		
	if (parentCode == tcRicohMakerNote &&
		tagCode == 0x2001 &&
		tagType == ttUndefined &&
		tagCount > 22)
		{
		
		char header [20];
		
		stream.SetReadPosition (tagOffset);
		
		stream.Get (header, sizeof (header));
		
		if (memcmp (header, "[Ricoh Camera Info]", 19) == 0)
			{
		
			ParseMakerNoteIFD (host,
							   stream,
							   tagCount - 20,
				   	  		   tagOffset + 20,
				   	  		   offsetDelta,
				   	  		   tagOffset + 20,
				   	  		   tagOffset + tagCount,
				   	  		   tcRicohMakerNoteCameraInfo);

			return;
			
			}
			
		}
		
	#if qDNGValidate
	
		{
		
		stream.SetReadPosition (tagOffset);
		
		if (gVerbose)
			{
					
			printf ("*");
				
			DumpTagValues (stream,
						   LookupTagType (tagType),
						   parentCode,
						   tagCode,
						   tagType,
						   tagCount);
			
			}
			
		// If type is ASCII, then parse anyway so we report any ASCII
		// NULL termination or character set errors.
			
		else if (tagType == ttAscii)
			{
			
			dng_string s;
			
			ParseStringTag (stream,
							parentCode,
							tagCode,
							tagCount,
							s,
							false);

			}
			
		}
	
	#endif
	
	}
Ejemplo n.º 2
0
bool dng_camera_profile_info::ParseExtended (dng_stream &stream)
	{

	try
		{

		// Offsets are relative to the start of this structure, not the entire file.

		uint64 startPosition = stream.Position ();

		// Read header. Like a TIFF header, but with different magic number
		// Plus all offsets are relative to the start of the IFD, not to the
		// stream or file.

		uint16 byteOrder = stream.Get_uint16 ();

		if (byteOrder == byteOrderMM)
			fBigEndian = true;

		else if (byteOrder == byteOrderII)
			fBigEndian = false;

		else
			return false;

		TempBigEndian setEndianness (stream, fBigEndian);

		uint16 magicNumber = stream.Get_uint16 ();

		if (magicNumber != magicExtendedProfile)
			{
			return false;
			}

		uint32 offset = stream.Get_uint32 ();

		stream.Skip (offset - 8);

		// Start on IFD entries.

		uint32 ifdEntries = stream.Get_uint16 ();

		if (ifdEntries < 1)
			{
			return false;
			}

		for (uint32 tag_index = 0; tag_index < ifdEntries; tag_index++)
			{

			stream.SetReadPosition (startPosition + 8 + 2 + tag_index * 12);

			uint16 tagCode  = stream.Get_uint16 ();
			uint32 tagType  = stream.Get_uint16 ();
			uint32 tagCount = stream.Get_uint32 ();

			uint64 tagOffset = stream.Position ();

			if (TagTypeSize (tagType) * tagCount > 4)
				{

				tagOffset = startPosition + stream.Get_uint32 ();

				stream.SetReadPosition (tagOffset);

				}

			if (!ParseTag (stream,
						   0,
						   tagCode,
						   tagType,
						   tagCount,
						   tagOffset))
				{

				#if qDNGValidate

				if (gVerbose)
					{

					stream.SetReadPosition (tagOffset);

					printf ("*");

					DumpTagValues (stream,
								   LookupTagType (tagType),
								   0,
								   tagCode,
								   tagType,
								   tagCount);

					}

				#endif

				}

			}

		return true;

		}

	catch (...)
		{

		// Eat parsing errors.

		}

	return false;

	}