fptiffcmn.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2012 by the Free Pascal development team
  4. Common stuff for Tiff image format.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************
  11. }
  12. unit FPTiffCmn;
  13. {$mode objfpc}{$H+}
  14. interface
  15. uses
  16. Classes, sysutils, FPimage;
  17. type
  18. TTiffRational = packed record
  19. Numerator, Denominator: DWord;
  20. end;
  21. const
  22. TiffHandlerName = 'Tagged Image File Format';
  23. TiffRational0: TTiffRational = (Numerator: 0; Denominator: 0);
  24. TiffRational72: TTiffRational = (Numerator: 72; Denominator: 1);
  25. // TFPCustomImage.Extra properties used by TFPReaderTiff and TFPWriterTiff
  26. TiffExtraPrefix = 'Tiff';
  27. TiffPhotoMetric = TiffExtraPrefix+'PhotoMetricInterpretation';
  28. TiffGrayBits = TiffExtraPrefix+'GrayBits'; // CMYK: key plate
  29. TiffRedBits = TiffExtraPrefix+'RedBits'; // CMYK: cyan
  30. TiffGreenBits = TiffExtraPrefix+'GreenBits'; // CMYK: magenta
  31. TiffBlueBits = TiffExtraPrefix+'BlueBits'; // CMYK: yellow
  32. TiffAlphaBits = TiffExtraPrefix+'AlphaBits';
  33. TiffArtist = TiffExtraPrefix+'Artist';
  34. TiffCopyright = TiffExtraPrefix+'Copyright';
  35. TiffDocumentName = TiffExtraPrefix+'DocumentName';
  36. TiffDateTime = TiffExtraPrefix+'DateTime';
  37. TiffImageDescription = TiffExtraPrefix+'ImageDescription';
  38. TiffHostComputer = TiffExtraPrefix+'HostComputer';
  39. TiffMake_ScannerManufacturer = TiffExtraPrefix+'Make_ScannerManufacturer';
  40. TiffModel_Scanner = TiffExtraPrefix+'Model_Scanner';
  41. TiffOrientation = TiffExtraPrefix+'Orientation';
  42. TiffResolutionUnit = TiffExtraPrefix+'ResolutionUnit';
  43. TiffSoftware = TiffExtraPrefix+'Software';
  44. TiffXResolution = TiffExtraPrefix+'XResolution';
  45. TiffYResolution = TiffExtraPrefix+'YResolution';
  46. TiffPageNumber = TiffExtraPrefix+'PageNumber'; // starting at 0
  47. TiffPageCount = TiffExtraPrefix+'PageCount'; // if >0 the image is a page
  48. TiffPageName = TiffExtraPrefix+'PageName';
  49. TiffIsThumbnail = TiffExtraPrefix+'IsThumbnail';
  50. TiffIsMask = TiffExtraPrefix+'IsMask';
  51. TiffTileWidth = TiffExtraPrefix+'TileWidth';
  52. TiffTileLength = TiffExtraPrefix+'TileLength';
  53. TiffCompression = TiffExtraPrefix+'Compression'; // number
  54. TiffCompressionNone = 1; { No Compression, but pack data into bytes as tightly as possible,
  55. leaving no unused bits (except at the end of a row). The component
  56. values are stored as an array of type BYTE. Each scan line (row)
  57. is padded to the next BYTE boundary. }
  58. TiffCompressionCCITTRLE = 2; { CCITT Group 3 1-Dimensional Modified Huffman run length encoding. }
  59. TiffCompressionCCITTFAX3 = 3; { CCITT Group 3 fax encoding }
  60. TiffCompressionCCITTFAX4 = 4; { CCITT Group 4 fax encoding }
  61. TiffCompressionLZW = 5; { LZW }
  62. TiffCompressionOldJPEG = 6; { JPEG old style}
  63. TiffCompressionJPEG = 7; { JPEG new style }
  64. TiffCompressionDeflateAdobe = 8; { Deflate Adobe style }
  65. TiffCompressionJBIGBW = 9; { RFC2301 JBIG black/white }
  66. TiffCompressionJBIGCol = 10; { RFC2301 JBIG color }
  67. TiffCompressionNeXT = 32766; { Next }
  68. TiffCompressionCCITTRLEW = 32771; { CCITTRLEW }
  69. TiffCompressionPackBits = 32773; { PackBits Compression, a simple byte-oriented run length scheme.
  70. See the PackBits section for details. Data Compression applies
  71. only to raster image data. All other TIFF fields are unaffected. }
  72. TiffCompressionThunderScan = 32809; { THUNDERSCAN }
  73. TiffCompressionIT8CTPAD = 32895; { IT8CTPAD }
  74. TiffCompressionIT8LW = 32896; { IT8LW }
  75. TiffCompressionIT8MP = 32897; { IT8MP }
  76. TiffCompressionIT8BL = 32898; { IT8BL }
  77. TiffCompressionPixarFilm = 32908; { PIXARFILM }
  78. TiffCompressionPixarLog = 32909; { PIXARLOG }
  79. TiffCompressionDeflateZLib = 32946; { DeflatePKZip }
  80. TiffCompressionDCS = 32947; { DCS }
  81. TiffCompressionJBIG = 34661; { JBIG }
  82. TiffCompressionSGILog = 34676; { SGILOG }
  83. TiffCompressionSGILog24 = 34677; { SGILOG24 }
  84. TiffCompressionJPEG2000 = 34712; { JP2000 }
  85. // Planar configuration - TIFF 6.0 spec p. 38
  86. TiffPlanarConfigurationChunky = 1; //Chunky format
  87. TiffPlanarConfigurationPlanar = 2; //Planar format
  88. type
  89. TTiffChunkType = (
  90. tctStrip,
  91. tctTile
  92. );
  93. { TTiffIFD - Image File Directory }
  94. TTiffIFD = class
  95. public
  96. IFDStart: DWord; // tiff position
  97. IFDNext: DWord; // tiff position
  98. Artist: String;
  99. BitsPerSample: DWord; // tiff position of entry
  100. BitsPerSampleArray: array of Word;
  101. CellLength: DWord;
  102. CellWidth: DWord;
  103. ColorMap: DWord;// tiff position of entry
  104. Compression: DWord;
  105. Predictor: Word;
  106. Copyright: string;
  107. DateAndTime: string;
  108. DocumentName: string;
  109. ExtraSamples: DWord;// tiff position of entry
  110. FillOrder: DWord;
  111. HostComputer: string;
  112. ImageDescription: string;
  113. ImageHeight: DWord;
  114. ImageIsMask: Boolean;
  115. ImageIsPage: Boolean;
  116. ImageIsThumbNail: Boolean;
  117. ImageWidth: DWord;
  118. Make_ScannerManufacturer: string;
  119. Model_Scanner: string;
  120. Orientation: DWord;
  121. PageNumber: word; // the page number starting at 0, the total number of pages is PageCount
  122. PageCount: word; // see PageNumber
  123. PageName: string;
  124. PhotoMetricInterpretation: DWord;
  125. PlanarConfiguration: DWord;
  126. ResolutionUnit: DWord;
  127. RowsPerStrip: DWord;
  128. SamplesPerPixel: DWord;
  129. Software: string;
  130. StripByteCounts: DWord;// tiff position of entry
  131. StripOffsets: DWord; // tiff position of entry
  132. TileWidth: DWord;
  133. TileLength: DWord; // = Height
  134. TileOffsets: DWord; // tiff position of entry
  135. TileByteCounts: DWord; // tiff position of entry
  136. Tresholding: DWord;
  137. XResolution: TTiffRational;
  138. YResolution: TTiffRational;
  139. // image
  140. Img: TFPCustomImage;
  141. FreeImg: boolean;
  142. RedBits: word;
  143. GreenBits: word;
  144. BlueBits: word;
  145. GrayBits: word;
  146. AlphaBits: word;
  147. BytesPerPixel: Word;
  148. procedure Clear;
  149. procedure Assign(IFD: TTiffIFD);
  150. procedure ReadFPImgExtras(Src: TFPCustomImage);
  151. function ImageLength: DWord; inline;
  152. constructor Create;
  153. destructor Destroy; override;
  154. end;
  155. function TiffRationalToStr(const r: TTiffRational): string;
  156. function StrToTiffRationalDef(const s: string; const Def: TTiffRational): TTiffRational;
  157. procedure ClearTiffExtras(Img: TFPCustomImage);
  158. procedure CopyTiffExtras(SrcImg, DestImg: TFPCustomImage);
  159. procedure WriteTiffExtras(Msg: string; Img: TFPCustomImage);
  160. function TiffCompressionName(c: Word): string;
  161. implementation
  162. function TiffRationalToStr(const r: TTiffRational): string;
  163. begin
  164. Result:=IntToStr(r.Numerator)+'/'+IntToStr(r.Denominator);
  165. end;
  166. function StrToTiffRationalDef(const s: string; const Def: TTiffRational
  167. ): TTiffRational;
  168. var
  169. p: LongInt;
  170. begin
  171. Result:=Def;
  172. p:=System.Pos('/',s);
  173. if p<1 then exit;
  174. Result.Numerator:=StrToIntDef(copy(s,1,p-1),TiffRational0.Numerator);
  175. Result.Denominator:=StrToIntDef(copy(s,p+1,length(s)),TiffRational0.Denominator);
  176. end;
  177. procedure ClearTiffExtras(Img: TFPCustomImage);
  178. var
  179. i: Integer;
  180. begin
  181. for i:=Img.ExtraCount-1 downto 0 do
  182. if SysUtils.CompareText(copy(Img.ExtraKey[i],1,4),'Tiff')=0 then
  183. Img.RemoveExtra(Img.ExtraKey[i]);
  184. end;
  185. procedure CopyTiffExtras(SrcImg, DestImg: TFPCustomImage);
  186. var
  187. i: Integer;
  188. begin
  189. ClearTiffExtras(DestImg);
  190. for i:=SrcImg.ExtraCount-1 downto 0 do
  191. if SysUtils.CompareText(copy(SrcImg.ExtraKey[i],1,4),'Tiff')=0 then
  192. DestImg.Extra[SrcImg.ExtraKey[i]]:=SrcImg.ExtraValue[i];
  193. end;
  194. procedure WriteTiffExtras(Msg: string; Img: TFPCustomImage);
  195. var
  196. i: Integer;
  197. begin
  198. writeln('WriteTiffExtras ',Msg);
  199. for i:=0 to Img.ExtraCount-1 do
  200. //if SysUtils.CompareText(copy(Img.ExtraKey[i],1,4),'Tiff')=0 then
  201. writeln(' ',i,' ',Img.ExtraKey[i],'=',Img.ExtraValue[i]);
  202. end;
  203. function TiffCompressionName(c: Word): string;
  204. begin
  205. case c of
  206. 1: Result:='no compression';
  207. 2: Result:='CCITT Group 3 1-Dimensional Modified Huffman run length encoding';
  208. 3: Result:='CCITT Group 3 fax encoding';
  209. 4: Result:='CCITT Group 4 fax encoding';
  210. 5: Result:='LZW';
  211. 6: Result:='JPEG old style';
  212. 7: Result:='JPEG';
  213. 8: Result:='Deflate Adobe style';
  214. 9: Result:='RFC2301 JBIG white/black';
  215. 10: Result:='RFC2301 JBIG color';
  216. 32766: Result:='NeXT';
  217. 32771: Result:='CCITTRLEW';
  218. 32773: Result:='PackBits';
  219. 32809: Result:='THUNDERSCAN';
  220. 32895: Result:='IT8CTPAD';
  221. 32896: Result:='IT8LW';
  222. 32897: Result:='IT8MP';
  223. 32898: Result:='IT8BL';
  224. 32908: Result:='PIXARFILM';
  225. 32909: Result:='PIXARLOG';
  226. 32946: Result:='Deflate ZLib';
  227. 32947: Result:='DCS';
  228. 34661: Result:='JBIG';
  229. 34676: Result:='SGILOG';
  230. 34677: Result:='SGILOG24';
  231. 34712: Result:='JP2000';
  232. else Result:='unknown('+IntToStr(c)+')';
  233. end;
  234. end;
  235. { TTiffIFD }
  236. procedure TTiffIFD.Clear;
  237. begin
  238. IFDStart:=0;
  239. IFDNext:=0;
  240. PhotoMetricInterpretation:=High(PhotoMetricInterpretation);
  241. PlanarConfiguration:=TiffPlanarConfigurationChunky;
  242. Compression:=TiffCompressionNone;
  243. Predictor:=1;
  244. ImageHeight:=0;
  245. ImageWidth:=0;
  246. ImageIsThumbNail:=false;
  247. ImageIsPage:=false;
  248. ImageIsMask:=false;
  249. BitsPerSample:=0;
  250. SetLength(BitsPerSampleArray,0);
  251. ResolutionUnit:=0;
  252. XResolution:=TiffRational0;
  253. YResolution:=TiffRational0;
  254. RowsPerStrip:=0;
  255. StripOffsets:=0;
  256. StripByteCounts:=0;
  257. SamplesPerPixel:=0;
  258. Artist:='';
  259. HostComputer:='';
  260. ImageDescription:='';
  261. Make_ScannerManufacturer:='';
  262. Model_Scanner:='';
  263. Copyright:='';
  264. DateAndTime:='';
  265. Software:='';
  266. CellWidth:=0;
  267. CellLength:=0;
  268. FillOrder:=0;
  269. Orientation:=0;
  270. PageNumber:=0;
  271. PageCount:=0;
  272. PageName:='';
  273. // tiles
  274. TileWidth:=0;
  275. TileLength:=0;
  276. TileOffsets:=0;
  277. TileByteCounts:=0;
  278. Tresholding:=0;
  279. RedBits:=0;
  280. GreenBits:=0;
  281. BlueBits:=0;
  282. GrayBits:=0;
  283. AlphaBits:=0;
  284. BytesPerPixel:=0;
  285. if FreeImg then begin
  286. FreeImg:=false;
  287. FreeAndNil(Img);
  288. end;
  289. end;
  290. procedure TTiffIFD.Assign(IFD: TTiffIFD);
  291. begin
  292. IFDStart:=IFD.IFDStart;
  293. IFDNext:=IFD.IFDNext;
  294. PhotoMetricInterpretation:=IFD.PhotoMetricInterpretation;
  295. PlanarConfiguration:=IFD.PlanarConfiguration;
  296. Compression:=IFD.Compression;
  297. Predictor:=IFD.Predictor;
  298. ImageHeight:=IFD.ImageHeight;
  299. ImageWidth:=IFD.ImageWidth;
  300. ImageIsThumbNail:=IFD.ImageIsThumbNail;
  301. ImageIsPage:=IFD.ImageIsPage;
  302. ImageIsMask:=IFD.ImageIsMask;
  303. BitsPerSample:=IFD.BitsPerSample;
  304. BitsPerSampleArray:=IFD.BitsPerSampleArray;
  305. ResolutionUnit:=IFD.ResolutionUnit;
  306. XResolution:=IFD.XResolution;
  307. YResolution:=IFD.YResolution;
  308. RowsPerStrip:=IFD.RowsPerStrip;
  309. StripOffsets:=IFD.StripOffsets;
  310. StripByteCounts:=IFD.StripByteCounts;
  311. SamplesPerPixel:=IFD.SamplesPerPixel;
  312. Artist:=IFD.Artist;
  313. HostComputer:=IFD.HostComputer;
  314. ImageDescription:=IFD.ImageDescription;
  315. Make_ScannerManufacturer:=IFD.Make_ScannerManufacturer;
  316. Model_Scanner:=IFD.Model_Scanner;
  317. Copyright:=IFD.Copyright;
  318. DateAndTime:=IFD.DateAndTime;
  319. Software:=IFD.Software;
  320. CellWidth:=IFD.CellWidth;
  321. CellLength:=IFD.CellLength;
  322. FillOrder:=IFD.FillOrder;
  323. Orientation:=IFD.Orientation;
  324. PageNumber:=IFD.PageNumber;
  325. PageCount:=IFD.PageCount;
  326. PageName:=IFD.PageName;
  327. // tiles
  328. TileWidth:=IFD.TileWidth;
  329. TileLength:=IFD.TileLength;
  330. TileOffsets:=IFD.TileOffsets;
  331. TileByteCounts:=IFD.TileByteCounts;
  332. Tresholding:=IFD.Tresholding;
  333. RedBits:=IFD.RedBits;
  334. GreenBits:=IFD.GreenBits;
  335. BlueBits:=IFD.BlueBits;
  336. GrayBits:=IFD.GrayBits;
  337. AlphaBits:=IFD.AlphaBits;
  338. if (Img<>nil) and (IFD.Img<>nil) then
  339. Img.Assign(IFD.Img);
  340. end;
  341. procedure TTiffIFD.ReadFPImgExtras(Src: TFPCustomImage);
  342. begin
  343. Clear;
  344. PhotoMetricInterpretation:=2;
  345. if Src.Extra[TiffPhotoMetric]<>'' then
  346. PhotoMetricInterpretation:=
  347. StrToInt64Def(Src.Extra[TiffPhotoMetric],High(PhotoMetricInterpretation));
  348. Artist:=Src.Extra[TiffArtist];
  349. Copyright:=Src.Extra[TiffCopyright];
  350. DocumentName:=Src.Extra[TiffDocumentName];
  351. DateAndTime:=Src.Extra[TiffDateTime];
  352. HostComputer:=Src.Extra[TiffHostComputer];
  353. Make_ScannerManufacturer:=Src.Extra[TiffMake_ScannerManufacturer];
  354. Model_Scanner:=Src.Extra[TiffModel_Scanner];
  355. ImageDescription:=Src.Extra[TiffImageDescription];
  356. Software:=Src.Extra[TiffSoftware];
  357. Orientation:=StrToIntDef(Src.Extra[TiffOrientation],1);
  358. if not (Orientation in [1..8]) then
  359. Orientation:=1;
  360. ResolutionUnit:=StrToIntDef(Src.Extra[TiffResolutionUnit],2);
  361. if not (ResolutionUnit in [1..3]) then
  362. ResolutionUnit:=2;
  363. XResolution:=StrToTiffRationalDef(Src.Extra[TiffXResolution],TiffRational72);
  364. YResolution:=StrToTiffRationalDef(Src.Extra[TiffYResolution],TiffRational72);
  365. PageNumber:=StrToIntDef(Src.Extra[TiffPageNumber],0);
  366. PageCount:=StrToIntDef(Src.Extra[TiffPageCount],0);
  367. PageName:=Src.Extra[TiffPageName];
  368. ImageIsPage:=PageCount>0;
  369. ImageIsThumbNail:=Src.Extra[TiffIsThumbnail]<>'';
  370. ImageIsMask:=Src.Extra[TiffIsMask]<>'';
  371. TileWidth:=StrToIntDef(Src.Extra[TiffTileWidth],0);
  372. TileLength:=StrToIntDef(Src.Extra[TiffTileLength],0);
  373. Compression:=StrToIntDef(Src.Extra[TiffCompression],TiffCompressionNone);
  374. end;
  375. function TTiffIFD.ImageLength: DWord;
  376. begin
  377. Result:=ImageHeight;
  378. end;
  379. constructor TTiffIFD.Create;
  380. begin
  381. PlanarConfiguration:=TiffPlanarConfigurationChunky;
  382. end;
  383. destructor TTiffIFD.Destroy;
  384. begin
  385. if FreeImg then
  386. FreeAndNil(Img);
  387. inherited Destroy;
  388. end;
  389. end.