Exemplo n.º 1
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;

	}
Exemplo n.º 2
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
	
	}
Exemplo n.º 3
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;

	}