/ delphi-google-api/libs/pngimage/pngimage.pas

http://delphi-google-api.googlecode.com/ · Pascal · 1941 lines · 1141 code · 179 blank · 621 comment · 72 complexity · 8b775ea61d45deafebc0137783d9a634 MD5 · raw file

Large files are truncated click here to view the full file

  1. {Portable Network Graphics Delphi 1.564 (31 July 2006) }
  2. {This is a full, open sourced implementation of png in Delphi }
  3. {It has native support for most of png features including the }
  4. {partial transparency, gamma and more. }
  5. {For the latest version, please be sure to check my website }
  6. {http://pngdelphi.sourceforge.net }
  7. {Gustavo Huffenbacher Daud (gustavo.daud@terra.com.br) }
  8. {
  9. Version 1.564
  10. 2006-07-25 BUG 1 - There was one GDI Palette object leak
  11. when assigning from other PNG (fixed)
  12. BUG 2 - Loosing color information when assigning png
  13. to bmp on lower screen depth system
  14. BUG 3 - There was a bug in TStream.GetSize
  15. (fixed thanks to Vladimir Panteleev)
  16. IMPROVE 1 - When assigning png to bmp now alpha information
  17. is drawn (simulated into a white background)
  18. Version 1.563
  19. 2006-07-25 BUG 1 - There was a memory bug in the main component
  20. destructor (fixed thanks to Steven L Brenner)
  21. BUG 2 - The packages name contained spaces which was
  22. causing some strange bugs in Delphi
  23. (fixed thanks to Martijn Saly)
  24. BUG 3 - Lots of fixes when handling palettes
  25. (bugs implemented in the last version)
  26. Fixed thanks to Gabriel Corneanu!!!
  27. BUG 4 - CreateAlpha was raising an error because it did
  28. not resized the palette chunk it created;
  29. Fixed thanks to Miha Sokolov
  30. IMPROVE 1 - Renamed the pngzlib.pas unit to zlibpas.pas
  31. as a tentative to all libraries use the same
  32. shared zlib implementation and to avoid including
  33. two or three times the same P-Code.
  34. (Gabriel Corneanu idea)
  35. Version 1.561
  36. 2006-05-17 BUG 1 - There was a bug in the method that draws semi
  37. transparent images (a memory leak). fixed.
  38. Version 1.56
  39. 2006-05-09 - IMPROVE 1 - Delphi standard TCanvas support is now implemented
  40. IMPROVE 2 - The PNG files may now be resized and created from
  41. scratch using CreateBlank, Resize, Width and Height
  42. BUG 1 - Fixed some bugs on handling tRNS transparencies
  43. BUG 2 - Fixed bugs related to palette handling
  44. Version 1.535
  45. 2006-04-21 - IMPROVE 1 - Now the library uses the latest ZLIB release (1.2.3)
  46. (thanks to: Roberto Della Pasqua
  47. http://www.dellapasqua.com/delphizlib/)
  48. Version 1.53
  49. 2006-04-14 -
  50. BUG 1 - Remove transparency was not working for
  51. RGB Alpha and Grayscale alpha. fixed
  52. BUG 2 - There was a bug were compressed text chunks no keyword
  53. name could not be read
  54. IMPROVE 1 - Add classes and methods to work with the pHYs chunk
  55. (including TPNGObject.DrawUsingPixelInformation)
  56. IMPROVE 3 - Included a property Version to return the library
  57. version
  58. IMPROVE 4 - New polish translation (thanks to Piotr Domanski)
  59. IMPROVE 5 - Now packages for delphi 5, 6, 7, 2005 and 2006
  60. Also Martijn Saly (thany) made some improvements in the library:
  61. IMPROVE 1 - SetPixel now works with grayscale
  62. IMPROVE 2 - Palette property now can be written using a
  63. windows handle
  64. Thanks !!
  65. Version 1.5
  66. 2005-06-29 - Fixed a lot of bugs using tips from mails that I´ve
  67. being receiving for some time
  68. BUG 1 - Loosing palette when assigning to TBitmap. fixed
  69. BUG 2 - SetPixels and GetPixels worked only with
  70. parameters in range 0..255. fixed
  71. BUG 3 - Force type address off using directive
  72. BUG 4 - TChunkzTXt contained an error
  73. BUG 5 - MaxIdatSize was not working correctly (fixed thanks
  74. to Gabriel Corneanu
  75. BUG 6 - Corrected german translation (thanks to Mael Horz)
  76. And the following improvements:
  77. IMPROVE 1 - Create ImageHandleValue properties as public in
  78. TChunkIHDR to get access to this handle
  79. IMPROVE 2 - Using SetStretchBltMode to improve stretch quality
  80. IMPROVE 3 - Scale is now working for alpha transparent images
  81. IMPROVE 4 - GammaTable propery is now public to support an
  82. article in the help file
  83. Version 1.4361
  84. 2003-03-04 - Fixed important bug for simple transparency when using
  85. RGB, Grayscale color modes
  86. Version 1.436
  87. 2003-03-04 - * NEW * Property Pixels for direct access to pixels
  88. * IMPROVED * Palette property (TPngObject) (read only)
  89. Slovenian traslation for the component (Miha Petelin)
  90. Help file update (scanline article/png->jpg example)
  91. Version 1.435
  92. 2003-11-03 - * NEW * New chunk implementation zTXt (method AddzTXt)
  93. * NEW * New compiler flags to store the extra 8 bits
  94. from 16 bits samples (when saving it is ignored), the
  95. extra data may be acessed using ExtraScanline property
  96. * Fixed * a bug on tIMe chunk
  97. French translation included (Thanks to IBE Software)
  98. Bugs fixed
  99. Version 1.432
  100. 2002-08-24 - * NEW * A new method, CreateAlpha will transform the
  101. current image into partial transparency.
  102. Help file updated with a new article on how to handle
  103. partial transparency.
  104. Version 1.431
  105. 2002-08-14 - Fixed and tested to work on:
  106. C++ Builder 3
  107. C++ Builder 5
  108. Delphi 3
  109. There was an error when setting TransparentColor, fixed
  110. New method, RemoveTransparency to remove image
  111. BIT TRANSPARENCY
  112. Version 1.43
  113. 2002-08-01 - * NEW * Support for Delphi 3 and C++ Builder 3
  114. Implements mostly some things that were missing,
  115. a few tweaks and fixes.
  116. Version 1.428
  117. 2002-07-24 - More minor fixes (thanks to Ian Boyd)
  118. Bit transparency fixes
  119. * NEW * Finally support to bit transparency
  120. (palette / rgb / grayscale -> all)
  121. Version 1.427
  122. 2002-07-19 - Lots of bugs and leaks fixed
  123. * NEW * method to easy adding text comments, AddtEXt
  124. * NEW * property for setting bit transparency,
  125. TransparentColor
  126. Version 1.426
  127. 2002-07-18 - Clipboard finally fixed and working
  128. Changed UseDelphi trigger to UseDelphi
  129. * NEW * Support for bit transparency bitmaps
  130. when assigning from/to TBitmap objects
  131. Altough it does not support drawing transparent
  132. parts of bit transparency pngs (only partial)
  133. it is closer than ever
  134. Version 1.425
  135. 2002-07-01 - Clipboard methods implemented
  136. Lots of bugs fixed
  137. Version 1.424
  138. 2002-05-16 - Scanline and AlphaScanline are now working correctly.
  139. New methods for handling the clipboard
  140. Version 1.423
  141. 2002-05-16 - * NEW * Partial transparency for 1, 2, 4 and 8 bits is
  142. also supported using the tRNS chunk (for palette and
  143. grayscaling).
  144. New bug fixes (Peter Haas).
  145. Version 1.422
  146. 2002-05-14 - Fixed some critical leaks, thanks to Peter Haas tips.
  147. New translation for German (Peter Haas).
  148. Version 1.421
  149. 2002-05-06 - Now uses new ZLIB version, 1.1.4 with some security
  150. fixes.
  151. LoadFromResourceID and LoadFromResourceName added and
  152. help file updated for that.
  153. The resources strings are now located in pnglang.pas.
  154. New translation for Brazilian Portuguese.
  155. Bugs fixed.
  156. IMPORTANT: As always I´m looking for bugs on the library. If
  157. anyone has found one, please send me an email and
  158. I will fix asap. Thanks for all the help and ideas
  159. I'm receiving so far.}
  160. {My email is : gustavo.daud@terra.com.br}
  161. {Website link : http://pngdelphi.sourceforge.net}
  162. {Gustavo Huffenbacher Daud}
  163. unit pngimage;
  164. interface
  165. {Triggers avaliable (edit the fields bellow)}
  166. {$TYPEDADDRESS OFF}
  167. {$DEFINE UseDelphi} //Disable fat vcl units(perfect for small apps)
  168. {$DEFINE ErrorOnUnknownCritical} //Error when finds an unknown critical chunk
  169. {$DEFINE CheckCRC} //Enables CRC checking
  170. {$DEFINE RegisterGraphic} //Registers TPNGObject to use with TPicture
  171. {$DEFINE PartialTransparentDraw} //Draws partial transparent images
  172. {$DEFINE Store16bits} //Stores the extra 8 bits from 16bits/sample
  173. {$RANGECHECKS OFF} {$J+}
  174. uses
  175. Windows {$IFDEF UseDelphi}, Classes, Graphics, SysUtils{$ENDIF},
  176. zlibpas, pnglang;
  177. const
  178. LibraryVersion = '1.564';
  179. {$IFNDEF UseDelphi}
  180. const
  181. soFromBeginning = 0;
  182. soFromCurrent = 1;
  183. soFromEnd = 2;
  184. {$ENDIF}
  185. const
  186. {ZLIB constants}
  187. ZLIBErrors: Array[-6..2] of string = ('incompatible version (-6)',
  188. 'buffer error (-5)', 'insufficient memory (-4)', 'data error (-3)',
  189. 'stream error (-2)', 'file error (-1)', '(0)', 'stream end (1)',
  190. 'need dictionary (2)');
  191. Z_NO_FLUSH = 0;
  192. Z_FINISH = 4;
  193. Z_STREAM_END = 1;
  194. {Avaliable PNG filters for mode 0}
  195. FILTER_NONE = 0;
  196. FILTER_SUB = 1;
  197. FILTER_UP = 2;
  198. FILTER_AVERAGE = 3;
  199. FILTER_PAETH = 4;
  200. {Avaliable color modes for PNG}
  201. COLOR_GRAYSCALE = 0;
  202. COLOR_RGB = 2;
  203. COLOR_PALETTE = 3;
  204. COLOR_GRAYSCALEALPHA = 4;
  205. COLOR_RGBALPHA = 6;
  206. type
  207. {$IFNDEF UseDelphi}
  208. {Custom exception handler}
  209. Exception = class(TObject)
  210. constructor Create(Msg: String);
  211. end;
  212. ExceptClass = class of Exception;
  213. TColor = ColorRef;
  214. {$ENDIF}
  215. {Error types}
  216. EPNGOutMemory = class(Exception);
  217. EPngError = class(Exception);
  218. EPngUnexpectedEnd = class(Exception);
  219. EPngInvalidCRC = class(Exception);
  220. EPngInvalidIHDR = class(Exception);
  221. EPNGMissingMultipleIDAT = class(Exception);
  222. EPNGZLIBError = class(Exception);
  223. EPNGInvalidPalette = class(Exception);
  224. EPNGInvalidFileHeader = class(Exception);
  225. EPNGIHDRNotFirst = class(Exception);
  226. EPNGNotExists = class(Exception);
  227. EPNGSizeExceeds = class(Exception);
  228. EPNGMissingPalette = class(Exception);
  229. EPNGUnknownCriticalChunk = class(Exception);
  230. EPNGUnknownCompression = class(Exception);
  231. EPNGUnknownInterlace = class(Exception);
  232. EPNGNoImageData = class(Exception);
  233. EPNGCouldNotLoadResource = class(Exception);
  234. EPNGCannotChangeTransparent = class(Exception);
  235. EPNGHeaderNotPresent = class(Exception);
  236. EPNGInvalidNewSize = class(Exception);
  237. EPNGInvalidSpec = class(Exception);
  238. type
  239. {Direct access to pixels using R,G,B}
  240. TRGBLine = array[word] of TRGBTriple;
  241. pRGBLine = ^TRGBLine;
  242. {Same as TBitmapInfo but with allocated space for}
  243. {palette entries}
  244. TMAXBITMAPINFO = packed record
  245. bmiHeader: TBitmapInfoHeader;
  246. bmiColors: packed array[0..255] of TRGBQuad;
  247. end;
  248. {Transparency mode for pngs}
  249. TPNGTransparencyMode = (ptmNone, ptmBit, ptmPartial);
  250. {Pointer to a cardinal type}
  251. pCardinal = ^Cardinal;
  252. {Access to a rgb pixel}
  253. pRGBPixel = ^TRGBPixel;
  254. TRGBPixel = packed record
  255. B, G, R: Byte;
  256. end;
  257. {Pointer to an array of bytes type}
  258. TByteArray = Array[Word] of Byte;
  259. pByteArray = ^TByteArray;
  260. {Forward}
  261. TPNGObject = class;
  262. pPointerArray = ^TPointerArray;
  263. TPointerArray = Array[Word] of Pointer;
  264. {Contains a list of objects}
  265. TPNGPointerList = class
  266. private
  267. fOwner: TPNGObject;
  268. fCount : Cardinal;
  269. fMemory: pPointerArray;
  270. function GetItem(Index: Cardinal): Pointer;
  271. procedure SetItem(Index: Cardinal; const Value: Pointer);
  272. protected
  273. {Removes an item}
  274. function Remove(Value: Pointer): Pointer; virtual;
  275. {Inserts an item}
  276. procedure Insert(Value: Pointer; Position: Cardinal);
  277. {Add a new item}
  278. procedure Add(Value: Pointer);
  279. {Returns an item}
  280. property Item[Index: Cardinal]: Pointer read GetItem write SetItem;
  281. {Set the size of the list}
  282. procedure SetSize(const Size: Cardinal);
  283. {Returns owner}
  284. property Owner: TPNGObject read fOwner;
  285. public
  286. {Returns number of items}
  287. property Count: Cardinal read fCount write SetSize;
  288. {Object being either created or destroyed}
  289. constructor Create(AOwner: TPNGObject);
  290. destructor Destroy; override;
  291. end;
  292. {Forward declaration}
  293. TChunk = class;
  294. TChunkClass = class of TChunk;
  295. {Same as TPNGPointerList but providing typecasted values}
  296. TPNGList = class(TPNGPointerList)
  297. private
  298. {Used with property Item}
  299. function GetItem(Index: Cardinal): TChunk;
  300. public
  301. {Finds the first item with this class}
  302. function FindChunk(ChunkClass: TChunkClass): TChunk;
  303. {Removes an item}
  304. procedure RemoveChunk(Chunk: TChunk); overload;
  305. {Add a new chunk using the class from the parameter}
  306. function Add(ChunkClass: TChunkClass): TChunk;
  307. {Returns pointer to the first chunk of class}
  308. function ItemFromClass(ChunkClass: TChunkClass): TChunk;
  309. {Returns a chunk item from the list}
  310. property Item[Index: Cardinal]: TChunk read GetItem;
  311. end;
  312. {$IFNDEF UseDelphi}
  313. {The STREAMs bellow are only needed in case delphi provided ones is not}
  314. {avaliable (UseDelphi trigger not set)}
  315. {Object becomes handles}
  316. TCanvas = THandle;
  317. TBitmap = HBitmap;
  318. {Trick to work}
  319. TPersistent = TObject;
  320. {Base class for all streams}
  321. TStream = class
  322. protected
  323. {Returning/setting size}
  324. function GetSize: Longint; virtual;
  325. procedure SetSize(const Value: Longint); virtual; abstract;
  326. {Returns/set position}
  327. function GetPosition: Longint; virtual;
  328. procedure SetPosition(const Value: Longint); virtual;
  329. public
  330. {Returns/sets current position}
  331. property Position: Longint read GetPosition write SetPosition;
  332. {Property returns/sets size}
  333. property Size: Longint read GetSize write SetSize;
  334. {Allows reading/writing data}
  335. function Read(var Buffer; Count: Longint): Cardinal; virtual; abstract;
  336. function Write(const Buffer; Count: Longint): Cardinal; virtual; abstract;
  337. {Copies from another Stream}
  338. function CopyFrom(Source: TStream;
  339. Count: Cardinal): Cardinal; virtual;
  340. {Seeks a stream position}
  341. function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;
  342. end;
  343. {File stream modes}
  344. TFileStreamMode = (fsmRead, fsmWrite, fsmCreate);
  345. TFileStreamModeSet = set of TFileStreamMode;
  346. {File stream for reading from files}
  347. TFileStream = class(TStream)
  348. private
  349. {Opened mode}
  350. Filemode: TFileStreamModeSet;
  351. {Handle}
  352. fHandle: THandle;
  353. protected
  354. {Set the size of the file}
  355. procedure SetSize(const Value: Longint); override;
  356. public
  357. {Seeks a file position}
  358. function Seek(Offset: Longint; Origin: Word): Longint; override;
  359. {Reads/writes data from/to the file}
  360. function Read(var Buffer; Count: Longint): Cardinal; override;
  361. function Write(const Buffer; Count: Longint): Cardinal; override;
  362. {Stream being created and destroy}
  363. constructor Create(Filename: String; Mode: TFileStreamModeSet);
  364. destructor Destroy; override;
  365. end;
  366. {Stream for reading from resources}
  367. TResourceStream = class(TStream)
  368. constructor Create(Instance: HInst; const ResName: String; ResType:PChar);
  369. private
  370. {Variables for reading}
  371. Size: Integer;
  372. Memory: Pointer;
  373. Position: Integer;
  374. protected
  375. {Set the size of the file}
  376. procedure SetSize(const Value: Longint); override;
  377. public
  378. {Stream processing}
  379. function Read(var Buffer; Count: Integer): Cardinal; override;
  380. function Seek(Offset: Integer; Origin: Word): Longint; override;
  381. function Write(const Buffer; Count: Longint): Cardinal; override;
  382. end;
  383. {$ENDIF}
  384. {Forward}
  385. TChunkIHDR = class;
  386. TChunkpHYs = class;
  387. {Interlace method}
  388. TInterlaceMethod = (imNone, imAdam7);
  389. {Compression level type}
  390. TCompressionLevel = 0..9;
  391. {Filters type}
  392. TFilter = (pfNone, pfSub, pfUp, pfAverage, pfPaeth);
  393. TFilters = set of TFilter;
  394. {Png implementation object}
  395. TPngObject = class{$IFDEF UseDelphi}(TGraphic){$ENDIF}
  396. protected
  397. {Inverse gamma table values}
  398. InverseGamma: Array[Byte] of Byte;
  399. procedure InitializeGamma;
  400. private
  401. {Canvas}
  402. {$IFDEF UseDelphi}fCanvas: TCanvas;{$ENDIF}
  403. {Filters to test to encode}
  404. fFilters: TFilters;
  405. {Compression level for ZLIB}
  406. fCompressionLevel: TCompressionLevel;
  407. {Maximum size for IDAT chunks}
  408. fMaxIdatSize: Integer;
  409. {Returns if image is interlaced}
  410. fInterlaceMethod: TInterlaceMethod;
  411. {Chunks object}
  412. fChunkList: TPngList;
  413. {Clear all chunks in the list}
  414. procedure ClearChunks;
  415. {Returns if header is present}
  416. function HeaderPresent: Boolean;
  417. procedure GetPixelInfo(var LineSize, Offset: Cardinal);
  418. {Returns linesize and byte offset for pixels}
  419. procedure SetMaxIdatSize(const Value: Integer);
  420. function GetAlphaScanline(const LineIndex: Integer): pByteArray;
  421. function GetScanline(const LineIndex: Integer): Pointer;
  422. {$IFDEF Store16bits}
  423. function GetExtraScanline(const LineIndex: Integer): Pointer;
  424. {$ENDIF}
  425. function GetPixelInformation: TChunkpHYs;
  426. function GetTransparencyMode: TPNGTransparencyMode;
  427. function GetTransparentColor: TColor;
  428. procedure SetTransparentColor(const Value: TColor);
  429. {Returns the version}
  430. function GetLibraryVersion: String;
  431. protected
  432. {Being created}
  433. BeingCreated: Boolean;
  434. {Returns / set the image palette}
  435. function GetPalette: HPALETTE; {$IFDEF UseDelphi}override;{$ENDIF}
  436. procedure SetPalette(Value: HPALETTE); {$IFDEF UseDelphi}override;{$ENDIF}
  437. procedure DoSetPalette(Value: HPALETTE; const UpdateColors: Boolean);
  438. {Returns/sets image width and height}
  439. function GetWidth: Integer; {$IFDEF UseDelphi}override;{$ENDIF}
  440. function GetHeight: Integer; {$IFDEF UseDelphi}override; {$ENDIF}
  441. procedure SetWidth(Value: Integer); {$IFDEF UseDelphi}override; {$ENDIF}
  442. procedure SetHeight(Value: Integer); {$IFDEF UseDelphi}override;{$ENDIF}
  443. {Assigns from another TPNGObject}
  444. procedure AssignPNG(Source: TPNGObject);
  445. {Returns if the image is empty}
  446. function GetEmpty: Boolean; {$IFDEF UseDelphi}override; {$ENDIF}
  447. {Used with property Header}
  448. function GetHeader: TChunkIHDR;
  449. {Draws using partial transparency}
  450. procedure DrawPartialTrans(DC: HDC; Rect: TRect);
  451. {$IFDEF UseDelphi}
  452. {Returns if the image is transparent}
  453. function GetTransparent: Boolean; override;
  454. {$ENDIF}
  455. {Returns a pixel}
  456. function GetPixels(const X, Y: Integer): TColor; virtual;
  457. procedure SetPixels(const X, Y: Integer; const Value: TColor); virtual;
  458. public
  459. {Gamma table array}
  460. GammaTable: Array[Byte] of Byte;
  461. {Resizes the PNG image}
  462. procedure Resize(const CX, CY: Integer);
  463. {Generates alpha information}
  464. procedure CreateAlpha;
  465. {Removes the image transparency}
  466. procedure RemoveTransparency;
  467. {Transparent color}
  468. property TransparentColor: TColor read GetTransparentColor write
  469. SetTransparentColor;
  470. {Add text chunk, TChunkTEXT, TChunkzTXT}
  471. procedure AddtEXt(const Keyword, Text: String);
  472. procedure AddzTXt(const Keyword, Text: String);
  473. {$IFDEF UseDelphi}
  474. {Saves to clipboard format (thanks to Antoine Pottern)}
  475. procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle;
  476. var APalette: HPalette); override;
  477. procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle;
  478. APalette: HPalette); override;
  479. {$ENDIF}
  480. {Calling errors}
  481. procedure RaiseError(ExceptionClass: ExceptClass; Text: String);
  482. {Returns a scanline from png}
  483. property Scanline[const Index: Integer]: Pointer read GetScanline;
  484. {$IFDEF Store16bits}
  485. property ExtraScanline[const Index: Integer]: Pointer read GetExtraScanline;
  486. {$ENDIF}
  487. {Used to return pixel information}
  488. function HasPixelInformation: Boolean;
  489. property PixelInformation: TChunkpHYs read GetPixelInformation;
  490. property AlphaScanline[const Index: Integer]: pByteArray read
  491. GetAlphaScanline;
  492. procedure DrawUsingPixelInformation(Canvas: TCanvas; Point: TPoint);
  493. {Canvas}
  494. {$IFDEF UseDelphi}property Canvas: TCanvas read fCanvas;{$ENDIF}
  495. {Returns pointer to the header}
  496. property Header: TChunkIHDR read GetHeader;
  497. {Returns the transparency mode used by this png}
  498. property TransparencyMode: TPNGTransparencyMode read GetTransparencyMode;
  499. {Assigns from another object}
  500. procedure Assign(Source: TPersistent);{$IFDEF UseDelphi}override;{$ENDIF}
  501. {Assigns to another object}
  502. procedure AssignTo(Dest: TPersistent);{$IFDEF UseDelphi}override;{$ENDIF}
  503. {Assigns from a windows bitmap handle}
  504. procedure AssignHandle(Handle: HBitmap; Transparent: Boolean;
  505. TransparentColor: ColorRef);
  506. {Draws the image into a canvas}
  507. procedure Draw(ACanvas: TCanvas; const Rect: TRect);
  508. {$IFDEF UseDelphi}override;{$ENDIF}
  509. {Width and height properties}
  510. property Width: Integer read GetWidth;
  511. property Height: Integer read GetHeight;
  512. {Returns if the image is interlaced}
  513. property InterlaceMethod: TInterlaceMethod read fInterlaceMethod
  514. write fInterlaceMethod;
  515. {Filters to test to encode}
  516. property Filters: TFilters read fFilters write fFilters;
  517. {Maximum size for IDAT chunks, default and minimum is 65536}
  518. property MaxIdatSize: Integer read fMaxIdatSize write SetMaxIdatSize;
  519. {Property to return if the image is empty or not}
  520. property Empty: Boolean read GetEmpty;
  521. {Compression level}
  522. property CompressionLevel: TCompressionLevel read fCompressionLevel
  523. write fCompressionLevel;
  524. {Access to the chunk list}
  525. property Chunks: TPngList read fChunkList;
  526. {Object being created and destroyed}
  527. constructor Create; {$IFDEF UseDelphi}override;{$ENDIF}
  528. constructor CreateBlank(ColorType, Bitdepth: Cardinal; cx, cy: Integer);
  529. destructor Destroy; override;
  530. {$IFNDEF UseDelphi}procedure LoadFromFile(const Filename: String);{$ENDIF}
  531. {$IFNDEF UseDelphi}procedure SaveToFile(const Filename: String);{$ENDIF}
  532. procedure LoadFromStream(Stream: TStream);
  533. {$IFDEF UseDelphi}override;{$ENDIF}
  534. procedure SaveToStream(Stream: TStream); {$IFDEF UseDelphi}override;{$ENDIF}
  535. {Loading the image from resources}
  536. procedure LoadFromResourceName(Instance: HInst; const Name: String);
  537. procedure LoadFromResourceID(Instance: HInst; ResID: Integer);
  538. {Access to the png pixels}
  539. property Pixels[const X, Y: Integer]: TColor read GetPixels write SetPixels;
  540. {Palette property}
  541. {$IFNDEF UseDelphi}property Palette: HPalette read GetPalette write
  542. SetPalette;{$ENDIF}
  543. {Returns the version}
  544. property Version: String read GetLibraryVersion;
  545. end;
  546. {Chunk name object}
  547. TChunkName = Array[0..3] of Char;
  548. {Global chunk object}
  549. TChunk = class
  550. private
  551. {Contains data}
  552. fData: Pointer;
  553. fDataSize: Cardinal;
  554. {Stores owner}
  555. fOwner: TPngObject;
  556. {Stores the chunk name}
  557. fName: TChunkName;
  558. {Returns pointer to the TChunkIHDR}
  559. function GetHeader: TChunkIHDR;
  560. {Used with property index}
  561. function GetIndex: Integer;
  562. {Should return chunk class/name}
  563. class function GetName: String; virtual;
  564. {Returns the chunk name}
  565. function GetChunkName: String;
  566. public
  567. {Returns index from list}
  568. property Index: Integer read GetIndex;
  569. {Returns pointer to the TChunkIHDR}
  570. property Header: TChunkIHDR read GetHeader;
  571. {Resize the data}
  572. procedure ResizeData(const NewSize: Cardinal);
  573. {Returns data and size}
  574. property Data: Pointer read fData;
  575. property DataSize: Cardinal read fDataSize;
  576. {Assigns from another TChunk}
  577. procedure Assign(Source: TChunk); virtual;
  578. {Returns owner}
  579. property Owner: TPngObject read fOwner;
  580. {Being destroyed/created}
  581. constructor Create(Owner: TPngObject); virtual;
  582. destructor Destroy; override;
  583. {Returns chunk class/name}
  584. property Name: String read GetChunkName;
  585. {Loads the chunk from a stream}
  586. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  587. Size: Integer): Boolean; virtual;
  588. {Saves the chunk to a stream}
  589. function SaveData(Stream: TStream): Boolean;
  590. function SaveToStream(Stream: TStream): Boolean; virtual;
  591. end;
  592. {Chunk classes}
  593. TChunkIEND = class(TChunk); {End chunk}
  594. {IHDR data}
  595. pIHDRData = ^TIHDRData;
  596. TIHDRData = packed record
  597. Width, Height: Cardinal;
  598. BitDepth,
  599. ColorType,
  600. CompressionMethod,
  601. FilterMethod,
  602. InterlaceMethod: Byte;
  603. end;
  604. {Information header chunk}
  605. TChunkIHDR = class(TChunk)
  606. private
  607. {Current image}
  608. ImageHandle: HBitmap;
  609. ImageDC: HDC;
  610. ImagePalette: HPalette;
  611. {Output windows bitmap}
  612. HasPalette: Boolean;
  613. BitmapInfo: TMaxBitmapInfo;
  614. {Stores the image bytes}
  615. {$IFDEF Store16bits}ExtraImageData: Pointer;{$ENDIF}
  616. ImageData: pointer;
  617. ImageAlpha: Pointer;
  618. {Contains all the ihdr data}
  619. IHDRData: TIHDRData;
  620. protected
  621. BytesPerRow: Integer;
  622. {Creates a grayscale palette}
  623. function CreateGrayscalePalette(Bitdepth: Integer): HPalette;
  624. {Copies the palette to the Device Independent bitmap header}
  625. procedure PaletteToDIB(Palette: HPalette);
  626. {Resizes the image data to fill the color type, bit depth, }
  627. {width and height parameters}
  628. procedure PrepareImageData;
  629. {Release allocated ImageData memory}
  630. procedure FreeImageData;
  631. public
  632. {Access to ImageHandle}
  633. property ImageHandleValue: HBitmap read ImageHandle;
  634. {Properties}
  635. property Width: Cardinal read IHDRData.Width write IHDRData.Width;
  636. property Height: Cardinal read IHDRData.Height write IHDRData.Height;
  637. property BitDepth: Byte read IHDRData.BitDepth write IHDRData.BitDepth;
  638. property ColorType: Byte read IHDRData.ColorType write IHDRData.ColorType;
  639. property CompressionMethod: Byte read IHDRData.CompressionMethod
  640. write IHDRData.CompressionMethod;
  641. property FilterMethod: Byte read IHDRData.FilterMethod
  642. write IHDRData.FilterMethod;
  643. property InterlaceMethod: Byte read IHDRData.InterlaceMethod
  644. write IHDRData.InterlaceMethod;
  645. {Loads the chunk from a stream}
  646. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  647. Size: Integer): Boolean; override;
  648. {Saves the chunk to a stream}
  649. function SaveToStream(Stream: TStream): Boolean; override;
  650. {Destructor/constructor}
  651. constructor Create(Owner: TPngObject); override;
  652. destructor Destroy; override;
  653. {Assigns from another TChunk}
  654. procedure Assign(Source: TChunk); override;
  655. end;
  656. {pHYs chunk}
  657. pUnitType = ^TUnitType;
  658. TUnitType = (utUnknown, utMeter);
  659. TChunkpHYs = class(TChunk)
  660. private
  661. fPPUnitX, fPPUnitY: Cardinal;
  662. fUnit: TUnitType;
  663. public
  664. {Returns the properties}
  665. property PPUnitX: Cardinal read fPPUnitX write fPPUnitX;
  666. property PPUnitY: Cardinal read fPPUnitY write fPPUnitY;
  667. property UnitType: TUnitType read fUnit write fUnit;
  668. {Loads the chunk from a stream}
  669. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  670. Size: Integer): Boolean; override;
  671. {Saves the chunk to a stream}
  672. function SaveToStream(Stream: TStream): Boolean; override;
  673. {Assigns from another TChunk}
  674. procedure Assign(Source: TChunk); override;
  675. end;
  676. {Gamma chunk}
  677. TChunkgAMA = class(TChunk)
  678. private
  679. {Returns/sets the value for the gamma chunk}
  680. function GetValue: Cardinal;
  681. procedure SetValue(const Value: Cardinal);
  682. public
  683. {Returns/sets gamma value}
  684. property Gamma: Cardinal read GetValue write SetValue;
  685. {Loading the chunk from a stream}
  686. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  687. Size: Integer): Boolean; override;
  688. {Being created}
  689. constructor Create(Owner: TPngObject); override;
  690. {Assigns from another TChunk}
  691. procedure Assign(Source: TChunk); override;
  692. end;
  693. {ZLIB Decompression extra information}
  694. TZStreamRec2 = packed record
  695. {From ZLIB}
  696. ZLIB: TZStreamRec;
  697. {Additional info}
  698. Data: Pointer;
  699. fStream : TStream;
  700. end;
  701. {Palette chunk}
  702. TChunkPLTE = class(TChunk)
  703. protected
  704. {Number of items in the palette}
  705. fCount: Integer;
  706. private
  707. {Contains the palette handle}
  708. function GetPaletteItem(Index: Byte): TRGBQuad;
  709. public
  710. {Returns the color for each item in the palette}
  711. property Item[Index: Byte]: TRGBQuad read GetPaletteItem;
  712. {Returns the number of items in the palette}
  713. property Count: Integer read fCount;
  714. {Loads the chunk from a stream}
  715. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  716. Size: Integer): Boolean; override;
  717. {Saves the chunk to a stream}
  718. function SaveToStream(Stream: TStream): Boolean; override;
  719. {Assigns from another TChunk}
  720. procedure Assign(Source: TChunk); override;
  721. end;
  722. {Transparency information}
  723. TChunktRNS = class(TChunk)
  724. private
  725. fBitTransparency: Boolean;
  726. function GetTransparentColor: ColorRef;
  727. {Returns the transparent color}
  728. procedure SetTransparentColor(const Value: ColorRef);
  729. public
  730. {Palette values for transparency}
  731. PaletteValues: Array[Byte] of Byte;
  732. {Returns if it uses bit transparency}
  733. property BitTransparency: Boolean read fBitTransparency;
  734. {Returns the transparent color}
  735. property TransparentColor: ColorRef read GetTransparentColor write
  736. SetTransparentColor;
  737. {Loads/saves the chunk from/to a stream}
  738. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  739. Size: Integer): Boolean; override;
  740. function SaveToStream(Stream: TStream): Boolean; override;
  741. {Assigns from another TChunk}
  742. procedure Assign(Source: TChunk); override;
  743. end;
  744. {Actual image information}
  745. TChunkIDAT = class(TChunk)
  746. private
  747. {Holds another pointer to the TChunkIHDR}
  748. Header: TChunkIHDR;
  749. {Stores temporary image width and height}
  750. ImageWidth, ImageHeight: Integer;
  751. {Size in bytes of each line and offset}
  752. Row_Bytes, Offset : Cardinal;
  753. {Contains data for the lines}
  754. Encode_Buffer: Array[0..5] of pByteArray;
  755. Row_Buffer: Array[Boolean] of pByteArray;
  756. {Variable to invert the Row_Buffer used}
  757. RowUsed: Boolean;
  758. {Ending position for the current IDAT chunk}
  759. EndPos: Integer;
  760. {Filter the current line}
  761. procedure FilterRow;
  762. {Filter to encode and returns the best filter}
  763. function FilterToEncode: Byte;
  764. {Reads ZLIB compressed data}
  765. function IDATZlibRead(var ZLIBStream: TZStreamRec2; Buffer: Pointer;
  766. Count: Integer; var EndPos: Integer; var crcfile: Cardinal): Integer;
  767. {Compress and writes IDAT data}
  768. procedure IDATZlibWrite(var ZLIBStream: TZStreamRec2; Buffer: Pointer;
  769. const Length: Cardinal);
  770. procedure FinishIDATZlib(var ZLIBStream: TZStreamRec2);
  771. {Prepares the palette}
  772. procedure PreparePalette;
  773. protected
  774. {Decode interlaced image}
  775. procedure DecodeInterlacedAdam7(Stream: TStream;
  776. var ZLIBStream: TZStreamRec2; const Size: Integer; var crcfile: Cardinal);
  777. {Decode non interlaced imaged}
  778. procedure DecodeNonInterlaced(Stream: TStream;
  779. var ZLIBStream: TZStreamRec2; const Size: Integer;
  780. var crcfile: Cardinal);
  781. protected
  782. {Encode non interlaced images}
  783. procedure EncodeNonInterlaced(Stream: TStream;
  784. var ZLIBStream: TZStreamRec2);
  785. {Encode interlaced images}
  786. procedure EncodeInterlacedAdam7(Stream: TStream;
  787. var ZLIBStream: TZStreamRec2);
  788. protected
  789. {Memory copy methods to decode}
  790. procedure CopyNonInterlacedRGB8(
  791. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  792. procedure CopyNonInterlacedRGB16(
  793. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  794. procedure CopyNonInterlacedPalette148(
  795. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  796. procedure CopyNonInterlacedPalette2(
  797. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  798. procedure CopyNonInterlacedGray2(
  799. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  800. procedure CopyNonInterlacedGrayscale16(
  801. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  802. procedure CopyNonInterlacedRGBAlpha8(
  803. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  804. procedure CopyNonInterlacedRGBAlpha16(
  805. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  806. procedure CopyNonInterlacedGrayscaleAlpha8(
  807. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  808. procedure CopyNonInterlacedGrayscaleAlpha16(
  809. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  810. procedure CopyInterlacedRGB8(const Pass: Byte;
  811. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  812. procedure CopyInterlacedRGB16(const Pass: Byte;
  813. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  814. procedure CopyInterlacedPalette148(const Pass: Byte;
  815. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  816. procedure CopyInterlacedPalette2(const Pass: Byte;
  817. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  818. procedure CopyInterlacedGray2(const Pass: Byte;
  819. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  820. procedure CopyInterlacedGrayscale16(const Pass: Byte;
  821. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  822. procedure CopyInterlacedRGBAlpha8(const Pass: Byte;
  823. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  824. procedure CopyInterlacedRGBAlpha16(const Pass: Byte;
  825. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  826. procedure CopyInterlacedGrayscaleAlpha8(const Pass: Byte;
  827. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  828. procedure CopyInterlacedGrayscaleAlpha16(const Pass: Byte;
  829. Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar);
  830. protected
  831. {Memory copy methods to encode}
  832. procedure EncodeNonInterlacedRGB8(Src, Dest, Trans: pChar);
  833. procedure EncodeNonInterlacedRGB16(Src, Dest, Trans: pChar);
  834. procedure EncodeNonInterlacedGrayscale16(Src, Dest, Trans: pChar);
  835. procedure EncodeNonInterlacedPalette148(Src, Dest, Trans: pChar);
  836. procedure EncodeNonInterlacedRGBAlpha8(Src, Dest, Trans: pChar);
  837. procedure EncodeNonInterlacedRGBAlpha16(Src, Dest, Trans: pChar);
  838. procedure EncodeNonInterlacedGrayscaleAlpha8(Src, Dest, Trans: pChar);
  839. procedure EncodeNonInterlacedGrayscaleAlpha16(Src, Dest, Trans: pChar);
  840. procedure EncodeInterlacedRGB8(const Pass: Byte; Src, Dest, Trans: pChar);
  841. procedure EncodeInterlacedRGB16(const Pass: Byte; Src, Dest, Trans: pChar);
  842. procedure EncodeInterlacedPalette148(const Pass: Byte;
  843. Src, Dest, Trans: pChar);
  844. procedure EncodeInterlacedGrayscale16(const Pass: Byte;
  845. Src, Dest, Trans: pChar);
  846. procedure EncodeInterlacedRGBAlpha8(const Pass: Byte;
  847. Src, Dest, Trans: pChar);
  848. procedure EncodeInterlacedRGBAlpha16(const Pass: Byte;
  849. Src, Dest, Trans: pChar);
  850. procedure EncodeInterlacedGrayscaleAlpha8(const Pass: Byte;
  851. Src, Dest, Trans: pChar);
  852. procedure EncodeInterlacedGrayscaleAlpha16(const Pass: Byte;
  853. Src, Dest, Trans: pChar);
  854. public
  855. {Loads the chunk from a stream}
  856. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  857. Size: Integer): Boolean; override;
  858. {Saves the chunk to a stream}
  859. function SaveToStream(Stream: TStream): Boolean; override;
  860. end;
  861. {Image last modification chunk}
  862. TChunktIME = class(TChunk)
  863. private
  864. {Holds the variables}
  865. fYear: Word;
  866. fMonth, fDay, fHour, fMinute, fSecond: Byte;
  867. public
  868. {Returns/sets variables}
  869. property Year: Word read fYear write fYear;
  870. property Month: Byte read fMonth write fMonth;
  871. property Day: Byte read fDay write fDay;
  872. property Hour: Byte read fHour write fHour;
  873. property Minute: Byte read fMinute write fMinute;
  874. property Second: Byte read fSecond write fSecond;
  875. {Loads the chunk from a stream}
  876. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  877. Size: Integer): Boolean; override;
  878. {Saves the chunk to a stream}
  879. function SaveToStream(Stream: TStream): Boolean; override;
  880. {Assigns from another TChunk}
  881. procedure Assign(Source: TChunk); override;
  882. end;
  883. {Textual data}
  884. TChunktEXt = class(TChunk)
  885. private
  886. fKeyword, fText: String;
  887. public
  888. {Keyword and text}
  889. property Keyword: String read fKeyword write fKeyword;
  890. property Text: String read fText write fText;
  891. {Loads the chunk from a stream}
  892. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  893. Size: Integer): Boolean; override;
  894. {Saves the chunk to a stream}
  895. function SaveToStream(Stream: TStream): Boolean; override;
  896. {Assigns from another TChunk}
  897. procedure Assign(Source: TChunk); override;
  898. end;
  899. {zTXT chunk}
  900. TChunkzTXt = class(TChunktEXt)
  901. {Loads the chunk from a stream}
  902. function LoadFromStream(Stream: TStream; const ChunkName: TChunkName;
  903. Size: Integer): Boolean; override;
  904. {Saves the chunk to a stream}
  905. function SaveToStream(Stream: TStream): Boolean; override;
  906. end;
  907. {Here we test if it's c++ builder or delphi version 3 or less}
  908. {$IFDEF VER110}{$DEFINE DelphiBuilder3Less}{$ENDIF}
  909. {$IFDEF VER100}{$DEFINE DelphiBuilder3Less}{$ENDIF}
  910. {$IFDEF VER93}{$DEFINE DelphiBuilder3Less}{$ENDIF}
  911. {$IFDEF VER90}{$DEFINE DelphiBuilder3Less}{$ENDIF}
  912. {$IFDEF VER80}{$DEFINE DelphiBuilder3Less}{$ENDIF}
  913. {Registers a new chunk class}
  914. procedure RegisterChunk(ChunkClass: TChunkClass);
  915. {Calculates crc}
  916. function update_crc(crc: {$IFNDEF DelphiBuilder3Less}Cardinal{$ELSE}Integer
  917. {$ENDIF}; buf: pByteArray; len: Integer): Cardinal;
  918. {Invert bytes using assembly}
  919. function ByteSwap(const a: integer): integer;
  920. implementation
  921. var
  922. ChunkClasses: TPngPointerList;
  923. {Table of CRCs of all 8-bit messages}
  924. crc_table: Array[0..255] of Cardinal;
  925. {Flag: has the table been computed? Initially false}
  926. crc_table_computed: Boolean;
  927. {Draw transparent image using transparent color}
  928. procedure DrawTransparentBitmap(dc: HDC; srcBits: Pointer;
  929. var srcHeader: TBitmapInfoHeader;
  930. srcBitmapInfo: pBitmapInfo; Rect: TRect; cTransparentColor: COLORREF);
  931. var
  932. cColor: COLORREF;
  933. bmAndBack, bmAndObject, bmAndMem: HBITMAP;
  934. bmBackOld, bmObjectOld, bmMemOld: HBITMAP;
  935. hdcMem, hdcBack, hdcObject, hdcTemp: HDC;
  936. ptSize, orgSize: TPOINT;
  937. OldBitmap, DrawBitmap: HBITMAP;
  938. begin
  939. hdcTemp := CreateCompatibleDC(dc);
  940. {Select the bitmap}
  941. DrawBitmap := CreateDIBitmap(dc, srcHeader, CBM_INIT, srcBits, srcBitmapInfo^,
  942. DIB_RGB_COLORS);
  943. OldBitmap := SelectObject(hdcTemp, DrawBitmap);
  944. {Get sizes}
  945. OrgSize.x := abs(srcHeader.biWidth);
  946. OrgSize.y := abs(srcHeader.biHeight);
  947. ptSize.x := Rect.Right - Rect.Left; // Get width of bitmap
  948. ptSize.y := Rect.Bottom - Rect.Top; // Get height of bitmap
  949. {Create some DCs to hold temporary data}
  950. hdcBack := CreateCompatibleDC(dc);
  951. hdcObject := CreateCompatibleDC(dc);
  952. hdcMem := CreateCompatibleDC(dc);
  953. // Create a bitmap for each DC. DCs are required for a number of
  954. // GDI functions.
  955. // Monochrome DCs
  956. bmAndBack := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil);
  957. bmAndObject := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil);
  958. bmAndMem := CreateCompatibleBitmap(dc, ptSize.x, ptSize.y);
  959. // Each DC must select a bitmap object to store pixel data.
  960. bmBackOld := SelectObject(hdcBack, bmAndBack);
  961. bmObjectOld := SelectObject(hdcObject, bmAndObject);
  962. bmMemOld := SelectObject(hdcMem, bmAndMem);
  963. // Set the background color of the source DC to the color.
  964. // contained in the parts of the bitmap that should be transparent
  965. cColor := SetBkColor(hdcTemp, cTransparentColor);
  966. // Create the object mask for the bitmap by performing a BitBlt
  967. // from the source bitmap to a monochrome bitmap.
  968. StretchBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
  969. orgSize.x, orgSize.y, SRCCOPY);
  970. // Set the background color of the source DC back to the original
  971. // color.
  972. SetBkColor(hdcTemp, cColor);
  973. // Create the inverse of the object mask.
  974. BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,
  975. NOTSRCCOPY);
  976. // Copy the background of the main DC to the destination.
  977. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, dc, Rect.Left, Rect.Top,
  978. SRCCOPY);
  979. // Mask out the places where the bitmap will be placed.
  980. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
  981. // Mask out the transparent colored pixels on the bitmap.
  982. // BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
  983. StretchBlt(hdcTemp, 0, 0, OrgSize.x, OrgSize.y, hdcBack, 0, 0,
  984. PtSize.x, PtSize.y, SRCAND);
  985. // XOR the bitmap with the background on the destination DC.
  986. StretchBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
  987. OrgSize.x, OrgSize.y, SRCPAINT);
  988. // Copy the destination to the screen.
  989. BitBlt(dc, Rect.Left, Rect.Top, ptSize.x, ptSize.y, hdcMem, 0, 0,
  990. SRCCOPY);
  991. // Delete the memory bitmaps.
  992. DeleteObject(SelectObject(hdcBack, bmBackOld));
  993. DeleteObject(SelectObject(hdcObject, bmObjectOld));
  994. DeleteObject(SelectObject(hdcMem, bmMemOld));
  995. DeleteObject(SelectObject(hdcTemp, OldBitmap));
  996. // Delete the memory DCs.
  997. DeleteDC(hdcMem);
  998. DeleteDC(hdcBack);
  999. DeleteDC(hdcObject);
  1000. DeleteDC(hdcTemp);
  1001. end;
  1002. {Make the table for a fast CRC.}
  1003. procedure make_crc_table;
  1004. var
  1005. c: Cardinal;
  1006. n, k: Integer;
  1007. begin
  1008. {fill the crc table}
  1009. for n := 0 to 255 do
  1010. begin
  1011. c := Cardinal(n);
  1012. for k := 0 to 7 do
  1013. begin
  1014. if Boolean(c and 1) then
  1015. c := $edb88320 xor (c shr 1)
  1016. else
  1017. c := c shr 1;
  1018. end;
  1019. crc_table[n] := c;
  1020. end;
  1021. {The table has already being computated}
  1022. crc_table_computed := true;
  1023. end;
  1024. {Update a running CRC with the bytes buf[0..len-1]--the CRC
  1025. should be initialized to all 1's, and the transmitted value
  1026. is the 1's complement of the final running CRC (see the
  1027. crc() routine below)).}
  1028. function update_crc(crc: {$IFNDEF DelphiBuilder3Less}Cardinal{$ELSE}Integer
  1029. {$ENDIF}; buf: pByteArray; len: Integer): Cardinal;
  1030. var
  1031. c: Cardinal;
  1032. n: Integer;
  1033. begin
  1034. c := crc;
  1035. {Create the crc table in case it has not being computed yet}
  1036. if not crc_table_computed then make_crc_table;
  1037. {Update}
  1038. for n := 0 to len - 1 do
  1039. c := crc_table[(c XOR buf^[n]) and $FF] XOR (c shr 8);
  1040. {Returns}
  1041. Result := c;
  1042. end;
  1043. {$IFNDEF UseDelphi}
  1044. function FileExists(Filename: String): Boolean;
  1045. var
  1046. FindFile: THandle;
  1047. FindData: TWin32FindData;
  1048. begin
  1049. FindFile := FindFirstFile(PChar(Filename), FindData);
  1050. Result := FindFile <> INVALID_HANDLE_VALUE;
  1051. if Result then Windows.FindClose(FindFile);
  1052. end;
  1053. {$ENDIF}
  1054. {$IFNDEF UseDelphi}
  1055. {Exception implementation}
  1056. constructor Exception.Create(Msg: String);
  1057. begin
  1058. end;
  1059. {$ENDIF}
  1060. {Calculates the paeth predictor}
  1061. function PaethPredictor(a, b, c: Byte): Byte;
  1062. var
  1063. pa, pb, pc: Integer;
  1064. begin
  1065. { a = left, b = above, c = upper left }
  1066. pa := abs(b - c); { distances to a, b, c }
  1067. pb := abs(a - c);
  1068. pc := abs(a + b - c * 2);
  1069. { return nearest of a, b, c, breaking ties in order a, b, c }
  1070. if (pa <= pb) and (pa <= pc) then
  1071. Result := a
  1072. else
  1073. if pb <= pc then
  1074. Result := b
  1075. else
  1076. Result := c;
  1077. end;
  1078. {Invert bytes using assembly}
  1079. function ByteSwap(const a: integer): integer;
  1080. asm
  1081. bswap eax
  1082. end;
  1083. function ByteSwap16(inp:word): word;
  1084. asm
  1085. bswap eax
  1086. shr eax, 16
  1087. end;
  1088. {Calculates number of bytes for the number of pixels using the}
  1089. {color mode in the paramenter}
  1090. function BytesForPixels(const Pixels: Integer; const ColorType,
  1091. BitDepth: Byte): Integer;
  1092. begin
  1093. case ColorType of
  1094. {Palette and grayscale contains a single value, for palette}
  1095. {an value of size 2^bitdepth pointing to the palette index}
  1096. {and grayscale the value from 0 to 2^bitdepth with color intesity}
  1097. COLOR_GRAYSCALE, COLOR_PALETTE:
  1098. Result := (Pixels * BitDepth + 7) div 8;
  1099. {RGB contains 3 values R, G, B with size 2^bitdepth each}
  1100. COLOR_RGB:
  1101. Result := (Pixels * BitDepth * 3) div 8;
  1102. {Contains one value followed by alpha value booth size 2^bitdepth}
  1103. COLOR_GRAYSCALEALPHA:
  1104. Result := (Pixels * BitDepth * 2) div 8;
  1105. {Contains four values size 2^bitdepth, Red, Green, Blue and alpha}
  1106. COLOR_RGBALPHA:
  1107. Result := (Pixels * BitDepth * 4) div 8;
  1108. else
  1109. Result := 0;
  1110. end {case ColorType}
  1111. end;
  1112. type
  1113. pChunkClassInfo = ^TChunkClassInfo;
  1114. TChunkClassInfo = record
  1115. ClassName: TChunkClass;
  1116. end;
  1117. {Register a chunk type}
  1118. procedure RegisterChunk(ChunkClass: TChunkClass);
  1119. var
  1120. NewClass: pChunkClassInfo;
  1121. begin
  1122. {In case the list object has not being created yet}
  1123. if ChunkClasses = nil then ChunkClasses := TPngPointerList.Create(nil);
  1124. {Add this new class}
  1125. new(NewClass);
  1126. NewClass^.ClassName := ChunkClass;
  1127. ChunkClasses.Add(NewClass);
  1128. end;
  1129. {Free chunk class list}
  1130. procedure FreeChunkClassList;
  1131. var
  1132. i: Integer;
  1133. begin
  1134. if (ChunkClasses <> nil) then
  1135. begin
  1136. FOR i := 0 TO ChunkClasses.Count - 1 do
  1137. Dispose(pChunkClassInfo(ChunkClasses.Item[i]));
  1138. ChunkClasses.Free;
  1139. end;
  1140. end;
  1141. {Registering of common chunk classes}
  1142. procedure RegisterCommonChunks;
  1143. begin
  1144. {Important chunks}
  1145. RegisterChunk(TChunkIEND);
  1146. RegisterChunk(TChunkIHDR);
  1147. RegisterChunk(TChunkIDAT);
  1148. RegisterChunk(TChunkPLTE);
  1149. RegisterChunk(TChunkgAMA);
  1150. RegisterChunk(TChunktRNS);
  1151. {Not so important chunks}
  1152. RegisterChunk(TChunkpHYs);
  1153. RegisterChunk(TChunktIME);
  1154. RegisterChunk(TChunktEXt);
  1155. RegisterChunk(TChunkzTXt);
  1156. end;
  1157. {Creates a new chunk of this class}
  1158. function CreateClassChunk(Owner: TPngObject; Name: TChunkName): TChunk;
  1159. var
  1160. i : Integer;
  1161. NewChunk: TChunkClass;
  1162. begin
  1163. {Looks for this chunk}
  1164. NewChunk := TChunk; {In case there is no registered class for this}
  1165. {Looks for this class in all registered chunks}
  1166. if Assigned(ChunkClasses) then
  1167. FOR i := 0 TO ChunkClasses.Count - 1 DO
  1168. begin
  1169. if pChunkClassInfo(ChunkClasses.Item[i])^.ClassName.GetName = Name then
  1170. begin
  1171. NewChunk := pChunkClassInfo(ChunkClasses.Item[i])^.ClassName;
  1172. break;
  1173. end;
  1174. end;
  1175. {Returns chunk class}
  1176. Result := NewChunk.Create(Owner);
  1177. Result.fName := Name;
  1178. end;
  1179. {ZLIB support}
  1180. const
  1181. ZLIBAllocate = High(Word);
  1182. {Initializes ZLIB for decompression}
  1183. function ZLIBInitInflate(Stream: TStream): TZStreamRec2;
  1184. begin
  1185. {Fill record}
  1186. Fillchar(Result, SIZEOF(TZStreamRec2), #0);
  1187. {Set internal record information}
  1188. with Result do
  1189. begin
  1190. GetMem(Data, ZLIBAllocate);
  1191. fStream := Stream;
  1192. end;
  1193. {Init decompression}
  1194. InflateInit_(Result.zlib, zlib_version, SIZEOF(TZStreamRec));
  1195. end;
  1196. {Initializes ZLIB for compression}
  1197. function ZLIBInitDeflate(Stream: TStream;
  1198. Level: TCompressionlevel; Size: Cardinal): TZStreamRec2;
  1199. begin
  1200. {Fill record}
  1201. Fillchar(Result, SIZEOF(TZStreamRec2), #0);
  1202. {Set internal record information}
  1203. with Result, ZLIB do
  1204. begin
  1205. GetMem(Data, Size);
  1206. fStream := Stream;
  1207. next_out := Data;
  1208. avail_out := Size;
  1209. end;
  1210. {Inits compression}
  1211. deflateInit_(Result.zlib, Level, zlib_version, sizeof(TZStreamRec));
  1212. end;
  1213. {Terminates ZLIB for compression}
  1214. procedure ZLIBTerminateDeflate(var ZLIBStream: TZStreamRec2);
  1215. begin
  1216. {Terminates decompression}
  1217. DeflateEnd(ZLIBStream.zlib);
  1218. {Free internal record}
  1219. FreeMem(ZLIBStream.Data, ZLIBAllocate);
  1220. end;
  1221. {Terminates ZLIB for decompression}
  1222. procedure ZLIBTerminateInflate(var ZLIBStream: TZStreamRec2);
  1223. begin
  1224. {Terminates decompression}
  1225. InflateEnd(ZLIBStream.zlib);
  1226. {Free internal record}
  1227. FreeMem(ZLIBStream.Data, ZLIBAllocate);
  1228. end;
  1229. {Decompresses ZLIB into a memory address}
  1230. function DecompressZLIB(const Input: Pointer; InputSize: Integer;
  1231. var Output: