//--------------------------------------------------------------------------- void File_Tiff::Read_Directory() { /* Each directory consist of 4 fields */ /* Get information for this directory */ Element_Begin0(); ifditem IfdItem; Get_X2 (IfdItem.Tag, "Tag"); Param_Info1(Tiff_Tag_Name(IfdItem.Tag)); Get_X2 (IfdItem.Type, "Type"); Param_Info1(Tiff_Type_Name(IfdItem.Type)); Get_X4 (IfdItem.Count, "Count"); Element_Name(Tiff_Tag_Name(IfdItem.Tag)); if (Tiff_Type_Size(IfdItem.Type)*IfdItem.Count<=4) { GetValueOffsetu(IfdItem); /* Padding up, skip dummy bytes */ if (Tiff_Type_Size(IfdItem.Type)==0) { if (Element_Offset+4<Element_Size) Skip_XX(Element_Size-(Element_Offset+4), "Unknown"); } else if (Tiff_Type_Size(IfdItem.Type)*IfdItem.Count<4) Skip_XX(Tiff_Type_Size(IfdItem.Type)*IfdItem.Count, "Padding"); } else { int32u IFDOffset; Get_X4 (IFDOffset, "IFDOffset"); IfdItems[IFDOffset]=IfdItem; } Element_End0(); }
//--------------------------------------------------------------------------- void File_Tiff::Header_Parse() { //Handling remaining IFD data if (!IfdItems.empty()) { if (File_Offset+Buffer_Offset!=IfdItems.begin()->first) IfdItems.clear(); //There was a problem during the seek, trashing remaining positions from last IFD else { Header_Fill_Code(IfdItems.begin()->second.Tag, Tiff_Tag_Name(IfdItems.begin()->second.Tag)); Header_Fill_Size(Tiff_Type_Size(IfdItems.begin()->second.Type)*IfdItems.begin()->second.Count); return; } } /* A tiff images consist in principle of two types of blocks, IFD's and data blocks */ /* Each datablock, which could be a image, tiles, transperancy filter is described by one IFD. */ /* These IFD's can be placed at any offset in the file and are linked in a chain fashion way. */ /* where one IFD points out where the next IFD is placed */ /* */ /* A creator of a tiff file must describe the "main image" in the first IFD, this means that a */ /* reader, such this one, only need to read the first IFD in order to get the bitdepth, resolution etc. */ /* of the main image. */ /* Read one IFD and print out the result */ /* Scan the tiff file for the IFD's (Image File Directory) */ /* As long as the IFD offset to the next IFD in the file is not 0 */ /* Get number of directories for this IFD */ int16u NrOfDirectories; Get_X2 (NrOfDirectories, "NrOfDirectories"); //Filling Header_Fill_Code(0xFFFFFFFF, "IFD"); //OxFFFFFFFF can not be a Tag, so using it as a magic value Header_Fill_Size(2+12*((int64u)NrOfDirectories)+4); //2 for header + 12 per directory + 4 for next IFD offset }
//--------------------------------------------------------------------------- void File_Dpx::GenericSectionHeader_Dpx() { Element_Name("Generic section header"); //Parsing Element_Begin1("File information"); std::string Version, CreationDate, Creator, Project, Copyright; int32u Size_Header, Size_Total, Size_Generic, Size_Industry, Size_User; Skip_String(4, "Magic number"); Get_X4 (Size_Header, "Offset to image data"); Get_String(8, Version, "Version number of header format"); Get_X4 (Size_Total, "Total image file size"); Skip_B4( "Ditto Key"); Get_X4 (Size_Generic, "Generic section header length"); Get_X4 (Size_Industry, "Industry specific header length"); Get_X4 (Size_User, "User-defined header length"); Skip_UTF8 (100, "FileName"); Get_String (24, CreationDate, "Creation Date"); Get_String (100, Creator, "Creator"); Get_String (200, Project, "Project"); Get_String (200, Copyright, "Right to use or copyright statement"); Skip_B4( "Encryption key"); Skip_XX(104, "Reserved for future use"); Element_End0(); Element_Begin1("Image information"); int32u Width, Height, PAR_H, PAR_V; int16u ImageElements; Info_B2(ImageOrientation, "Image orientation");Param_Info1(DPX_Orientation[ImageOrientation]); Get_X2 (ImageElements, "Number of image elements"); if (ImageElements>8) ImageElements=8; Get_X4 (Width, "Pixels per line"); Get_X4 (Height, "Lines per image element"); for(int16u ImageElement=0; ImageElement<ImageElements; ImageElement++) GenericSectionHeader_Dpx_ImageElement(); if (ImageElements!=8) Skip_XX((8-ImageElements)*72, "Padding"); Skip_XX(52, "Reserved for future use"); Element_End0(); Element_Begin1("Image source information"); Skip_B4( "X Offset"); Skip_B4( "Y Offset"); Skip_BF4( "X center"); Skip_BF4( "Y center"); Skip_B4( "X original size"); Skip_B4( "Y original size"); Skip_UTF8(100, "Source image filename"); Skip_UTF8(24, "Source image date/time"); Skip_UTF8(32, "Input device name"); Skip_UTF8(32, "Input device serial number"); Element_Begin1("Border validity"); Skip_B2( "XL border"); Skip_B2( "XR border"); Skip_B2( "YT border"); Skip_B2( "YB border"); Element_End0(); Get_X4 (PAR_H, "Pixel ratio : horizontal"); Get_X4 (PAR_V, "Pixel ratio : vertical"); Element_Begin1("Additional source image information"); Skip_BF4( "X scanned size"); Skip_BF4( "Y scanned size"); Skip_XX(20, "Reserved for future use"); Element_End0(); FILLING_BEGIN(); //Coherency tests if (File_Offset+Buffer_Offset+Size_Total!=Config->File_Current_Size) Size_Total=(int32u)(Config->File_Current_Size-(File_Offset+Buffer_Offset)); //The total size is bigger than the real size if (Size_Generic==(int32u)-1) Size_Generic=(int32u)Element_Size; if (Size_Industry==(int32u)-1) Size_Industry=0; if (Size_User==(int32u)-1) Size_User=0; if (Size_Generic+Size_Industry+Size_User>Size_Header || Size_Header>Size_Total) { Reject(); return; } //Filling sizes Sizes.push_back(Size_Header); Sizes.push_back(Size_Industry); Sizes.push_back(Size_User); Sizes.push_back(Size_Header-(Size_Generic+Size_Industry+Size_User)); //Size of padding Sizes.push_back(Size_Total-Size_Header); //Size of image //Filling meta if (Frame_Count==0) { Fill(Stream_General, 0, General_Encoded_Date, CreationDate); //ToDo: transform it in UTC Fill(StreamKind_Last, StreamPos_Last, "Encoded_Date", CreationDate); //ToDo: transform it in UTC Fill(Stream_General, 0, General_Encoded_Library, Creator); Fill(StreamKind_Last, StreamPos_Last, "Encoded_Library", Creator); Fill(Stream_General, 0, "Project", Project); //ToDo: map to a MediaInfo field (which one?) Fill(Stream_General, 0, General_Copyright, Copyright); Fill(StreamKind_Last, StreamPos_Last, "Format", "DPX"); if (Version.size()>2 && Version[0]=='V' && Version[1]>='0' && Version[2]<='9') Version.insert(1, "ersion "); Fill(StreamKind_Last, StreamPos_Last, "Format_Version", Version); Fill(Stream_General, 0, General_Format_Version, Version); Fill(StreamKind_Last, StreamPos_Last, "Width", Width); Fill(StreamKind_Last, StreamPos_Last, "Height", Height); if (PAR_V && PAR_H!=(int32u)-1 && PAR_V!=(int32u)-1) Fill(StreamKind_Last, StreamPos_Last, "PixelAspectRatio", ((float)PAR_H)/PAR_V); else Fill(StreamKind_Last, StreamPos_Last, "PixelAspectRatio", (float)1, 3); } FILLING_END(); }