示例#1
0
void dng_info::ParseIFD (dng_host &host,
						 dng_stream &stream,
						 dng_exif *exif,
						 dng_shared *shared,
						 dng_ifd *ifd,
						 uint64 ifdOffset,
						 int64 offsetDelta,
						 uint32 parentCode)
	{
	
	#if qDNGValidate

	bool isMakerNote = (parentCode >= tcFirstMakerNoteIFD &&
						parentCode <= tcLastMakerNoteIFD);
	
	#endif

	stream.SetReadPosition (ifdOffset);
	
	if (ifd)
		{
		ifd->fThisIFD = ifdOffset;
		}
	
	uint32 ifdEntries = stream.Get_uint16 ();
	
	#if qDNGValidate
	
	if (gVerbose)
		{
		
		printf ("%s: Offset = %u, Entries = %u\n\n",
				LookupParentCode (parentCode),
			    (unsigned) ifdOffset, 
			    (unsigned) ifdEntries);
		
		}
		
	if ((ifdOffset & 1) && !isMakerNote)
		{
		
		char message [256];
	
		sprintf (message,
				 "%s has odd offset (%u)",
				 LookupParentCode (parentCode),
				 (unsigned) ifdOffset);
					 
		ReportWarning (message);
		
		}
		
	#endif
		
	uint32 prev_tag_code = 0;
		
	for (uint32 tag_index = 0; tag_index < ifdEntries; tag_index++)
		{
		
		stream.SetReadPosition (ifdOffset + 2 + tag_index * 12);
		
		uint32 tagCode  = stream.Get_uint16 ();
		uint32 tagType  = stream.Get_uint16 ();
		
		// Minolta 7D files have a bug in the EXIF block where the count
		// is wrong, and we run off into next IFD link.  So if abort parsing
		// if we get a zero code/type combinations.
		
		if (tagCode == 0 && tagType == 0)
			{
			
			#if qDNGValidate
			
			char message [256];
	
			sprintf (message,
					 "%s had zero/zero tag code/type entry",
					 LookupParentCode (parentCode));
					 
			ReportWarning (message);
			
			#endif
			
			return;
			
			}
		
		uint32 tagCount = stream.Get_uint32 ();
		
		#if qDNGValidate

			{
		
			if (tag_index > 0 && tagCode <= prev_tag_code && !isMakerNote)
				{
				
				char message [256];
		
				sprintf (message,
						 "%s tags are not sorted in ascending numerical order",
						 LookupParentCode (parentCode));
						 
				ReportWarning (message);
				
				}
				
			}
			
		#endif
			
		prev_tag_code = tagCode;
		
		uint32 tag_type_size = TagTypeSize (tagType);
		
		if (tag_type_size == 0)
			{
			
			#if qDNGValidate
			
				{
			
				char message [256];
		
				sprintf (message,
						 "%s %s has unknown type (%u)",
						 LookupParentCode (parentCode),
						 LookupTagCode (parentCode, tagCode),
						 (unsigned) tagType);
						 
				ReportWarning (message);
							 
				}
				
			#endif
					 
			continue;
			
			}
			
		uint64 tagOffset = ifdOffset + 2 + tag_index * 12 + 8;
		
		if (tagCount * tag_type_size > 4)
			{
			
			tagOffset = stream.Get_uint32 ();
			
			#if qDNGValidate
			
				{
			
				if (!(ifdOffset & 1) && 
				     (tagOffset & 1) &&
				    !isMakerNote     &&
				    parentCode != tcKodakDCRPrivateIFD &&
					parentCode != tcKodakKDCPrivateIFD)
					{
					
					char message [256];
		
					sprintf (message,
							 "%s %s has odd data offset (%u)",
						 	 LookupParentCode (parentCode),
						 	 LookupTagCode (parentCode, tagCode),
							 (unsigned) tagOffset);
							 
					ReportWarning (message);
						 
					}
					
				}
				
			#endif
				
			tagOffset += offsetDelta;
				
			stream.SetReadPosition (tagOffset);
			
			}
			
		ParseTag (host,
				  stream,
			      exif,
				  shared,
				  ifd,
				  parentCode,
				  tagCode,
				  tagType,
				  tagCount,
				  tagOffset,
				  offsetDelta);
			
		}
		
	stream.SetReadPosition (ifdOffset + 2 + ifdEntries * 12);
	
	uint32 nextIFD = stream.Get_uint32 ();
	
	#if qDNGValidate
		
	if (gVerbose)
		{
		printf ("NextIFD = %u\n", (unsigned) nextIFD);
		}
		
	#endif
		
	if (ifd)
		{
		ifd->fNextIFD = nextIFD;
		}
		
	#if qDNGValidate

	if (nextIFD)
		{
		
		if (parentCode != 0 &&
				(parentCode < tcFirstChainedIFD ||
				 parentCode > tcLastChainedIFD  ))
			{

			char message [256];

			sprintf (message,
					 "%s has an unexpected non-zero NextIFD (%u)",
				 	 LookupParentCode (parentCode),
				 	 (unsigned) nextIFD);
					 
			ReportWarning (message);
					 
			}

		}
		
	if (gVerbose)
		{
		printf ("\n");
		}

	#endif
		
	}
示例#2
0
bool dng_camera_profile_info::ParseTag (dng_stream &stream,
										uint32 parentCode,
										uint32 tagCode,
										uint32 tagType,
										uint32 tagCount,
										uint64 tagOffset)
	{

	switch (tagCode)
		{

		case tcCalibrationIlluminant1:
			{

			CheckTagType (parentCode, tagCode, tagType, ttShort);

			CheckTagCount (parentCode, tagCode, tagCount, 1);

			fCalibrationIlluminant1 = stream.TagValue_uint32 (tagType);

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("CalibrationIlluminant1: %s\n",
						LookupLightSource (fCalibrationIlluminant1));

				}

			#endif

			break;

			}

		case tcCalibrationIlluminant2:
			{

			CheckTagType (parentCode, tagCode, tagType, ttShort);

			CheckTagCount (parentCode, tagCode, tagCount, 1);

			fCalibrationIlluminant2 = stream.TagValue_uint32 (tagType);

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("CalibrationIlluminant2: %s\n",
						LookupLightSource (fCalibrationIlluminant2));

				}

			#endif

			break;

			}

		case tcColorMatrix1:
			{

			CheckTagType (parentCode, tagCode, tagType, ttSRational);

			if (fColorPlanes == 0)
				{

				fColorPlanes = Pin_uint32 (0, tagCount / 3, kMaxColorPlanes);

				}

			if (!CheckColorImage (parentCode, tagCode, fColorPlanes))
				return false;

			if (!ParseMatrixTag (stream,
								 parentCode,
								 tagCode,
								 tagType,
								 tagCount,
								 fColorPlanes,
								 3,
								 fColorMatrix1))
				return false;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ColorMatrix1:\n");

				DumpMatrix (fColorMatrix1);

				}

			#endif

			break;

			}

		case tcColorMatrix2:
			{

			CheckTagType (parentCode, tagCode, tagType, ttSRational);

			if (!CheckColorImage (parentCode, tagCode, fColorPlanes))
				return false;

			if (!ParseMatrixTag (stream,
								 parentCode,
								 tagCode,
								 tagType,
								 tagCount,
								 fColorPlanes,
								 3,
								 fColorMatrix2))
				return false;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ColorMatrix2:\n");

				DumpMatrix (fColorMatrix2);

				}

			#endif

			break;

			}

		case tcForwardMatrix1:
			{

			CheckTagType (parentCode, tagCode, tagType, ttSRational);

			if (!CheckColorImage (parentCode, tagCode, fColorPlanes))
				return false;

			if (!ParseMatrixTag (stream,
								 parentCode,
								 tagCode,
								 tagType,
								 tagCount,
								 3,
								 fColorPlanes,
								 fForwardMatrix1))
				return false;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ForwardMatrix1:\n");

				DumpMatrix (fForwardMatrix1);

				}

			#endif

			break;

			}

		case tcForwardMatrix2:
			{

			CheckTagType (parentCode, tagCode, tagType, ttSRational);

			if (!CheckColorImage (parentCode, tagCode, fColorPlanes))
				return false;

			if (!ParseMatrixTag (stream,
								 parentCode,
								 tagCode,
								 tagType,
								 tagCount,
								 3,
								 fColorPlanes,
								 fForwardMatrix2))
				return false;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ForwardMatrix2:\n");

				DumpMatrix (fForwardMatrix2);

				}

			#endif

			break;

			}

		case tcReductionMatrix1:
			{

			CheckTagType (parentCode, tagCode, tagType, ttSRational);

			if (!CheckColorImage (parentCode, tagCode, fColorPlanes))
				return false;

			if (!ParseMatrixTag (stream,
								 parentCode,
								 tagCode,
								 tagType,
								 tagCount,
								 3,
								 fColorPlanes,
								 fReductionMatrix1))
				return false;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ReductionMatrix1:\n");

				DumpMatrix (fReductionMatrix1);

				}

			#endif

			break;

			}

		case tcReductionMatrix2:
			{

			CheckTagType (parentCode, tagCode, tagType, ttSRational);

			if (!CheckColorImage (parentCode, tagCode, fColorPlanes))
				return false;

			if (!ParseMatrixTag (stream,
								 parentCode,
								 tagCode,
								 tagType,
								 tagCount,
								 3,
								 fColorPlanes,
								 fReductionMatrix2))
				return false;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ReductionMatrix2:\n");

				DumpMatrix (fReductionMatrix2);

				}

			#endif

			break;

			}

		case tcProfileCalibrationSignature:
			{

			CheckTagType (parentCode, tagCode, tagType, ttAscii, ttByte);

			ParseStringTag (stream,
							parentCode,
							tagCode,
							tagCount,
							fProfileCalibrationSignature,
							false,
							false);

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileCalibrationSignature: ");

				DumpString (fProfileCalibrationSignature);

				printf ("\n");

				}

			#endif

			break;

			}

		case tcProfileName:
			{

			CheckTagType (parentCode, tagCode, tagType, ttAscii, ttByte);

			ParseStringTag (stream,
							parentCode,
							tagCode,
							tagCount,
							fProfileName,
							false,
							false);

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileName: ");

				DumpString (fProfileName);

				printf ("\n");

				}

			#endif

			break;

			}

		case tcProfileCopyright:
			{

			CheckTagType (parentCode, tagCode, tagType, ttAscii, ttByte);

			ParseStringTag (stream,
							parentCode,
							tagCode,
							tagCount,
							fProfileCopyright,
							false,
							false);

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileCopyright: ");

				DumpString (fProfileCopyright);

				printf ("\n");

				}

			#endif

			break;

			}

		case tcProfileEmbedPolicy:
			{

			CheckTagType (parentCode, tagCode, tagType, ttLong);

			CheckTagCount (parentCode, tagCode, tagCount, 1);

			fEmbedPolicy = stream.TagValue_uint32 (tagType);

			#if qDNGValidate

			if (gVerbose)
				{

				const char *policy;

				switch (fEmbedPolicy)
					{

					case pepAllowCopying:
						policy = "Allow copying";
						break;

					case pepEmbedIfUsed:
						policy = "Embed if used";
						break;

					case pepEmbedNever:
						policy = "Embed never";
						break;

					case pepNoRestrictions:
						policy = "No restrictions";
						break;

					default:
						policy = "INVALID VALUE";

					}

				printf ("ProfileEmbedPolicy: %s\n", policy);

				}

			#endif

			break;

			}

		case tcProfileHueSatMapDims:
			{

			CheckTagType (parentCode, tagCode, tagType, ttLong);

			CheckTagCount (parentCode, tagCode, tagCount, 2, 3);

			fProfileHues = stream.TagValue_uint32 (tagType);
			fProfileSats = stream.TagValue_uint32 (tagType);

			if (tagCount > 2)
				fProfileVals = stream.TagValue_uint32 (tagType);
			else
				fProfileVals = 1;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileHueSatMapDims: Hues = %u, Sats = %u, Vals = %u\n",
						(unsigned) fProfileHues,
						(unsigned) fProfileSats,
						(unsigned) fProfileVals);

				}

			#endif

			break;

			}

		case tcProfileHueSatMapData1:
			{

			if (!CheckTagType (parentCode, tagCode, tagType, ttFloat))
				return false;

			bool skipSat0 = (tagCount == fProfileHues *
										(fProfileSats - 1) *
										 fProfileVals * 3);

			if (!skipSat0)
				{

				if (!CheckTagCount (parentCode, tagCode, tagCount, fProfileHues *
																   fProfileSats *
																   fProfileVals * 3))
					return false;

				}

			fBigEndian = stream.BigEndian ();

			fHueSatDeltas1Offset = tagOffset;
			fHueSatDeltas1Count  = tagCount;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileHueSatMapData1:\n");

				DumpHueSatMap (stream,
							   fProfileHues,
							   fProfileSats,
							   fProfileVals,
							   skipSat0);

				}

			#endif

			break;

			}

		case tcProfileHueSatMapData2:
			{

			if (!CheckTagType (parentCode, tagCode, tagType, ttFloat))
				return false;

			bool skipSat0 = (tagCount == fProfileHues *
										(fProfileSats - 1) *
										 fProfileVals * 3);

			if (!skipSat0)
				{

				if (!CheckTagCount (parentCode, tagCode, tagCount, fProfileHues *
																   fProfileSats *
																   fProfileVals * 3))
					return false;

				}

			fBigEndian = stream.BigEndian ();

			fHueSatDeltas2Offset = tagOffset;
			fHueSatDeltas2Count  = tagCount;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileHueSatMapData2:\n");

				DumpHueSatMap (stream,
							   fProfileHues,
							   fProfileSats,
							   fProfileVals,
							   skipSat0);

				}

			#endif

			break;

			}

		case tcProfileLookTableDims:
			{

			CheckTagType (parentCode, tagCode, tagType, ttLong);

			CheckTagCount (parentCode, tagCode, tagCount, 2, 3);

			fLookTableHues = stream.TagValue_uint32 (tagType);
			fLookTableSats = stream.TagValue_uint32 (tagType);

			if (tagCount > 2)
				fLookTableVals = stream.TagValue_uint32 (tagType);
			else
				fLookTableVals = 1;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileLookTableDims: Hues = %u, Sats = %u, Vals = %u\n",
						(unsigned) fLookTableHues,
						(unsigned) fLookTableSats,
						(unsigned) fLookTableVals);

				}

			#endif

			break;

			}

		case tcProfileLookTableData:
			{

			if (!CheckTagType (parentCode, tagCode, tagType, ttFloat))
				return false;

			bool skipSat0 = (tagCount == fLookTableHues *
										(fLookTableSats - 1) *
										 fLookTableVals * 3);

			if (!skipSat0)
				{

				if (!CheckTagCount (parentCode, tagCode, tagCount, fLookTableHues *
																   fLookTableSats *
																   fLookTableVals * 3))
					return false;

				}

			fBigEndian = stream.BigEndian ();

			fLookTableOffset = tagOffset;
			fLookTableCount  = tagCount;

			#if qDNGValidate

			if (gVerbose)
				{

				printf ("ProfileLookTableData:\n");

				DumpHueSatMap (stream,
							   fLookTableHues,
							   fLookTableSats,
							   fLookTableVals,
							   skipSat0);

				}

			#endif

			break;

			}

		case tcProfileToneCurve:
			{

			if (!CheckTagType (parentCode, tagCode, tagType, ttFloat))
				return false;

			if (!CheckTagCount (parentCode, tagCode, tagCount, 4, tagCount))
				return false;

			if ((tagCount & 1) != 0)
				{

				#if qDNGValidate

					{

					char message [256];

					sprintf (message,
							 "%s %s has odd count (%u)",
							 LookupParentCode (parentCode),
							 LookupTagCode (parentCode, tagCode),
							 (unsigned) tagCount);

					ReportWarning (message);

					}

				#endif

				return false;

				}

			fBigEndian = stream.BigEndian ();

			fToneCurveOffset = tagOffset;
			fToneCurveCount  = tagCount;

			#if qDNGValidate

			if (gVerbose)
				{

				DumpTagValues (stream,
							   "Coord",
							   parentCode,
							   tagCode,
							   tagType,
							   tagCount);


				}

			#endif

			break;

			}

		case tcUniqueCameraModel:
			{

			// Note: This code is only used when parsing stand-alone
			// profiles.  The embedded profiles are assumed to be restricted
			// to the model they are embedded in.

			CheckTagType (parentCode, tagCode, tagType, ttAscii);

			ParseStringTag (stream,
							parentCode,
							tagCode,
							tagCount,
							fUniqueCameraModel,
							false);

			bool didTrim = fUniqueCameraModel.TrimTrailingBlanks ();

			#if qDNGValidate

			if (didTrim)
				{

				ReportWarning ("UniqueCameraModel string has trailing blanks");

				}

			if (gVerbose)
				{

				printf ("UniqueCameraModel: ");

				DumpString (fUniqueCameraModel);

				printf ("\n");

				}

			#else

			(void) didTrim;		// Unused

			#endif

			break;

			}

		default:
			{

			return false;

			}

		}

	return true;

	}