1 {
2 Vampyre Imaging Library
3 by Marek Mauder
4 http://imaginglib.sourceforge.net
6 The contents of this file are used with permission, subject to the Mozilla
7 Public License Version 1.1 (the "License"); you may not use this file except
8 in compliance with the License. You may obtain a copy of the License at
9 http://www.mozilla.org/MPL/MPL-1.1.html
11 Software distributed under the License is distributed on an "AS IS" basis,
12 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
13 the specific language governing rights and limitations under the License.
15 Alternatively, the contents of this file may be used under the terms of the
16 GNU Lesser General Public License (the "LGPL License"), in which case the
17 provisions of the LGPL License are applicable instead of those above.
18 If you wish to allow use of your version of this file only under the terms
19 of the LGPL License and not to allow others to use your version of this file
20 under the MPL, indicate your decision by deleting the provisions above and
21 replace them with the notice and other provisions required by the LGPL
22 License. If you do not delete the provisions above, a recipient may use
23 your version of this file under either the MPL or the LGPL License.
25 For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html
26 }
28 { This unit contains VCL/LCL TGraphic descendant which uses Imaging library
29 for saving and loading.}
32 {$I ImagingOptions.inc}
34 interface
36 {$IFDEF LCL}
37 {$DEFINE COMPONENT_SET_LCL}
38 {$UNDEF COMPONENT_SET_VCL}
39 {$ENDIF}
41 {$IF not Defined(COMPONENT_SET_LCL) and not Defined(COMPONENT_SET_VCL)}
42 // If no component sets should be used just include empty unit.
43 //DOC-IGNORE-BEGIN
44 implementation
45 //DOC-IGNORE-END
46 {$ELSE}
48 uses
50 {$IFDEF MSWINDOWS}
51 Windows,
52 {$ENDIF}
53 {$IFDEF COMPONENT_SET_VCL}
54 Graphics,
55 {$ENDIF}
56 {$IFDEF COMPONENT_SET_LCL}
57 InterfaceBase,
58 GraphType,
59 Graphics,
60 LCLType,
61 LCLIntf,
62 {$ENDIF}
65 type
66 { Graphic class which uses Imaging to load images.
67 It has standard TBitmap class as ancestor and it can
68 Assign also to/from TImageData structres and TBaseImage
69 classes. For saving is uses inherited TBitmap methods.
70 This class is automatically registered to TPicture for all
71 file extensions supported by Imaging (useful only for loading).
72 If you just want to load images in various formats you can use this
73 class or simply use TPicture.LoadFromXXX which will create this class
74 automatically. For TGraphic class that saves with Imaging look
75 at TImagingGraphicForSave class.}
77 protected
80 public
83 { Loads new image from the stream. It can load all image
84 file formats supported by Imaging (and enabled of course)
85 even though it is called by descendant class capable of
86 saving only one file format.}
88 { Copies the image contained in Source to this graphic object.
89 Supports also TBaseImage descendants from ImagingClasses unit. }
91 { Copies the image contained in TBaseImage to this graphic object.}
93 { Copies the current image to TBaseImage object.}
95 { Copies the image contained in TImageData structure to this graphic object.}
97 { Copies the current image to TImageData structure.}
103 { Base class for file format specific TGraphic classes that use
104 Imaging for saving. Each descendant class can load all file formats
105 supported by Imaging but save only one format (TImagingBitmap
106 for *.bmp, TImagingJpeg for *.jpg). Format specific classes also
107 allow easy access to Imaging options that affect saving of files
108 (they are properties here).}
110 protected
114 public
116 { Saves the current image to the stream. It is saved in the
117 file format according to the DefaultFileExt property.
118 So each descendant class can save some other file format.}
120 { Returns TImageFileFormat descendant for this graphic class.}
122 {$IFDEF COMPONENT_SET_LCL}
123 { Returns file extensions of this graphic class.}
125 { Returns default MIME type of this graphic class.}
127 {$ENDIF}
128 { Default (the most common) file extension of this graphic class.}
134 {$IFNDEF DONT_LINK_BITMAP}
135 { TImagingGraphic descendant for loading/saving Windows bitmaps.
136 VCL/CLX/LCL all have native support for bitmaps so you might
137 want to disable this class (although you can save bitmaps with
138 RLE compression with this class).}
140 protected
142 public
146 { See ImagingBitmapRLE option for details.}
149 {$ENDIF}
151 {$IFNDEF DONT_LINK_JPEG}
152 { TImagingGraphic descendant for loading/saving JPEG images.}
154 protected
157 public
161 {$IFDEF COMPONENT_SET_LCL}
163 {$ENDIF}
164 { See ImagingJpegQuality option for details.}
166 { See ImagingJpegProgressive option for details.}
169 {$ENDIF}
171 {$IFNDEF DONT_LINK_PNG}
172 { TImagingGraphic descendant for loading/saving PNG images.}
174 protected
177 public
181 { See ImagingPNGPreFilter option for details.}
183 { See ImagingPNGCompressLevel option for details.}
186 {$ENDIF}
188 {$IFNDEF DONT_LINK_GIF}
189 { TImagingGraphic descendant for loading/saving GIF images.}
191 public
194 {$ENDIF}
196 {$IFNDEF DONT_LINK_TARGA}
197 { TImagingGraphic descendant for loading/saving Targa images.}
199 protected
201 public
205 { See ImagingTargaRLE option for details.}
208 {$ENDIF}
210 {$IFNDEF DONT_LINK_DDS}
211 { Compresssion type used when saving DDS files by TImagingDds.}
214 { TImagingGraphic descendant for loading/saving DDS images.}
216 protected
218 public
222 { You can choose compression type used when saving DDS file.
223 dcNone means that file will be saved in the current bitmaps pixel format.}
226 {$ENDIF}
228 {$IFNDEF DONT_LINK_MNG}
229 { TImagingGraphic descendant for loading/saving MNG images.}
231 protected
238 public
242 {$IFDEF COMPONENT_SET_LCL}
244 {$ENDIF}
245 { See ImagingMNGLossyCompression option for details.}
247 { See ImagingMNGLossyAlpha option for details.}
249 { See ImagingMNGPreFilter option for details.}
251 { See ImagingMNGCompressLevel option for details.}
253 { See ImagingMNGQuality option for details.}
255 { See ImagingMNGProgressive option for details.}
258 {$ENDIF}
260 {$IFNDEF DONT_LINK_JNG}
261 { TImagingGraphic descendant for loading/saving JNG images.}
263 protected
269 public
273 { See ImagingJNGLossyAlpha option for details.}
275 { See ImagingJNGPreFilter option for details.}
277 { See ImagingJNGCompressLevel option for details.}
279 { See ImagingJNGQuality option for details.}
281 { See ImagingJNGProgressive option for details.}
284 {$ENDIF}
286 { Returns bitmap pixel format with the closest match with given data format.}
288 { Returns data format with closest match with given bitmap pixel format.}
291 { Converts TImageData structure to VCL/CLX/LCL bitmap.}
293 { Converts VCL/CLX/LCL bitmap to TImageData structure.}
295 { Converts TBaseImage instance to VCL/CLX/LCL bitmap.}
297 { Converts VCL/CLX/LCL bitmap to TBaseImage. Image must exist before
298 procedure is called. It overwrites its current image data.
299 When Image is TMultiImage only the current image level is overwritten.}
302 { Displays image stored in TImageData structure onto TCanvas. This procedure
303 draws image without converting from Imaging format to TBitmap.
304 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
305 when you want displaying images that change frequently (because converting to
306 TBitmap by ConvertImageDataToBitmap is generally slow). Dest and Src
307 rectangles represent coordinates in the form (X1, Y1, X2, Y2).}
308 procedure DisplayImageData(DstCanvas: TCanvas; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
309 { Displays image onto TCanvas at position [DstX, DstY]. This procedure
310 draws image without converting from Imaging format to TBitmap.
311 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
312 when you want displaying images that change frequently (because converting to
313 TBitmap by ConvertImageDataToBitmap is generally slow).}
315 { Displays image onto TCanvas to rectangle DstRect. This procedure
316 draws image without converting from Imaging format to TBitmap.
317 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
318 when you want displaying images that change frequently (because converting to
319 TBitmap by ConvertImageDataToBitmap is generally slow).}
321 { Displays part of the image specified by SrcRect onto TCanvas to rectangle DstRect.
322 This procedure draws image without converting from Imaging format to TBitmap.
323 Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
324 when you want displaying images that change frequently (because converting to
325 TBitmap by ConvertImageDataToBitmap is generally slow).}
326 procedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage; const SrcRect: TRect); overload;
328 {$IFDEF MSWINDOWS}
329 { Displays image stored in TImageData structure onto Windows device context.
330 Behaviour is the same as of DisplayImageData.}
331 procedure DisplayImageDataOnDC(DC: HDC; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
332 {$ENDIF}
334 implementation
336 uses
337 {$IF Defined(LCL)}
338 {$IF Defined(LCLGTK2)}
340 {$IFEND}
341 {$IFEND}
342 {$IFNDEF DONT_LINK_BITMAP}
343 ImagingBitmap,
344 {$ENDIF}
345 {$IFNDEF DONT_LINK_JPEG}
346 ImagingJpeg,
347 {$ENDIF}
348 {$IFNDEF DONT_LINK_GIF}
349 ImagingGif,
350 {$ENDIF}
351 {$IFNDEF DONT_LINK_TARGA}
352 ImagingTarga,
353 {$ENDIF}
354 {$IFNDEF DONT_LINK_DDS}
355 ImagingDds,
356 {$ENDIF}
357 {$IF not Defined(DONT_LINK_PNG) or not Defined(DONT_LINK_MNG) or not Defined(DONT_LINK_JNG)}
358 ImagingNetworkGraphics,
359 {$IFEND}
362 resourcestring
369 { Registers types to VCL/LCL.}
371 var
375 var
377 begin
380 TImagingGraphic);
384 var
386 begin
392 begin
397 {$IFNDEF DONT_LINK_TARGA}
400 {$ENDIF}
401 {$IFNDEF DONT_LINK_DDS}
404 {$ENDIF}
405 {$IFNDEF DONT_LINK_JNG}
408 {$ENDIF}
409 {$IFNDEF DONT_LINK_MNG}
412 {$ENDIF}
413 {$IFNDEF DONT_LINK_GIF}
416 {$ENDIF}
417 {$IFNDEF DONT_LINK_PNG}
418 {$IFDEF COMPONENT_SET_LCL}
419 // Unregister LazarusĀ“ default PNG loader which crashes on some PNG files
421 {$ENDIF}
424 {$ENDIF}
425 {$IFNDEF DONT_LINK_JPEG}
428 {$ENDIF}
429 {$IFNDEF DONT_LINK_BITMAP}
432 {$ENDIF}
435 { Unregisters types from VCL/LCL.}
437 begin
438 {$IFNDEF DONT_LINK_BITMAP}
441 {$ENDIF}
442 {$IFNDEF DONT_LINK_JPEG}
445 {$ENDIF}
446 {$IFNDEF DONT_LINK_PNG}
449 {$ENDIF}
450 {$IFNDEF DONT_LINK_GIF}
453 {$ENDIF}
454 {$IFNDEF DONT_LINK_TARGA}
457 {$ENDIF}
458 {$IFNDEF DONT_LINK_DDS}
461 {$ENDIF}
467 begin
469 {$IFDEF COMPONENT_SET_VCL}
473 {$ENDIF}
474 ifA8R8G8B8,
476 else
482 begin
489 else
495 var
500 {$IFDEF COMPONENT_SET_VCL}
502 {$ENDIF}
503 {$IFDEF COMPONENT_SET_LCL}
506 {$ENDIF}
507 begin
512 begin
513 // Some indexed images may have valid alpha data, dont lose it!
514 // (e.g. transparent 8bit PNG or GIF images)
519 begin
520 // Convert from formats not supported by Graphics unit
525 else
526 begin
527 {$IFDEF COMPONENT_SET_VCL}
532 else
534 {$ELSE}
536 {$ENDIF}
541 end
542 else
550 {$IFDEF COMPONENT_SET_VCL}
556 begin
557 // Copy palette, this must be done before copying bits
563 begin
570 // Copy scanlines
574 // Delphi 2009 and newer support alpha transparency fro TBitmap
575 {$IF Defined(DELPHI) and (CompilerVersion >= 20.0)}
578 {$IFEND}
580 {$ENDIF}
581 {$IFDEF COMPONENT_SET_LCL}
582 // Create 32bit raw image from image data
585 begin
607 // Create bitmap from raw image
609 begin
613 {$ENDIF}
619 var
623 {$IFDEF COMPONENT_SET_VCL}
626 {$ENDIF}
627 {$IFDEF COMPONENT_SET_LCL}
630 {$ENDIF}
631 begin
632 {$IFDEF COMPONENT_SET_LCL}
633 // In the current Lazarus 0.9.10 Bitmap.PixelFormat property is useless.
634 // We cannot change bitmap's format by changing it (it will just release
635 // old image but not convert it to new format) nor we can determine bitmaps's
636 // current format (it is usually set to pfDevice). So bitmap's format is obtained
637 // trough RawImage api and cannot be changed to mirror some Imaging format
638 // (so formats with no coresponding Imaging format cannot be saved now).
645 Format := ifA1R5G5B5
646 else
652 else
655 {$ELSE}
658 begin
659 // Convert from formats not supported by Imaging (1/4 bit)
662 else
666 {$ENDIF}
675 {$IFDEF COMPONENT_SET_VCL}
678 begin
679 // Copy palette
685 begin
692 // Copy scanlines
695 {$ENDIF}
696 {$IFDEF COMPONENT_SET_LCL}
697 // Get raw image from bitmap (mask handle must be 0 or expect violations)
699 begin
702 // Copy scanlines
704 begin
708 // May need to swap RB order, depends on wifget set
714 {$ENDIF}
718 begin
723 begin
727 {$IFDEF MSWINDOWS}
728 procedure DisplayImageDataOnDC(DC: HDC; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
729 var
733 begin
735 begin
741 begin
755 try
760 begin
761 // StretchDIBits may fail on some ocassions (error 487, http://support.microsoft.com/kb/269585).
762 // This fallback is slow but works every time. Thanks to Sergey Galezdinov for the fix.
764 try
766 StretchBlt(DC, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left, DstRect.Bottom - DstRect.Top,
768 finally
772 finally
777 {$ENDIF}
779 procedure DisplayImageData(DstCanvas: TCanvas; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
781 begin
784 {$ELSEIF Defined(LCLGTK2)}
785 type
790 var
792 begin
801 var
805 begin
807 begin
823 begin
825 try
827 // Swap R-B channels for GTK display compatability!
831 finally
833 end
834 else
835 try
836 // Create new image with desired dimensions
838 // Stretch pixels from old image to new one TResizeFilter = (rfNearest, rfBilinear, rfBicubic);
841 // Swap R-B channels for GTK display compatability!
845 finally
847 end
851 {$ELSE}
852 begin
855 {$IFEND}
858 begin
864 begin
868 procedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage; const SrcRect: TRect);
869 begin
874 { TImagingGraphic class implementation }
877 begin
883 begin
888 var
890 begin
892 try
895 finally
901 var
903 begin
905 begin
907 end
909 begin
914 end
915 else
920 begin
923 else
928 begin
934 begin
940 begin
946 begin
952 { TImagingGraphicForSave class implementation }
955 begin
963 var
965 begin
967 begin
969 try
974 finally
981 begin
985 {$IFDEF COMPONENT_SET_LCL}
987 begin
992 begin
995 {$ENDIF}
997 {$IFNDEF DONT_LINK_BITMAP}
999 { TImagingBitmap class implementation }
1002 begin
1008 begin
1013 begin
1019 {$ENDIF}
1021 {$IFNDEF DONT_LINK_JPEG}
1023 { TImagingJpeg class implementation }
1026 begin
1033 begin
1037 {$IFDEF COMPONENT_SET_LCL}
1039 begin
1042 {$ENDIF}
1045 begin
1053 {$ENDIF}
1055 {$IFNDEF DONT_LINK_PNG}
1057 { TImagingPNG class implementation }
1060 begin
1067 begin
1072 begin
1079 {$ENDIF}
1081 {$IFNDEF DONT_LINK_GIF}
1083 { TImagingGIF class implementation}
1086 begin
1090 {$ENDIF}
1092 {$IFNDEF DONT_LINK_TARGA}
1094 { TImagingTarga class implementation }
1097 begin
1103 begin
1108 begin
1114 {$ENDIF}
1116 {$IFNDEF DONT_LINK_DDS}
1118 { TImagingDDS class implementation }
1121 begin
1127 begin
1132 begin
1147 {$ENDIF}
1149 {$IFNDEF DONT_LINK_MNG}
1151 { TImagingMNG class implementation }
1154 begin
1165 begin
1169 {$IFDEF COMPONENT_SET_LCL}
1171 begin
1174 {$ENDIF}
1177 begin
1188 {$ENDIF}
1190 {$IFNDEF DONT_LINK_JNG}
1192 { TImagingJNG class implementation }
1195 begin
1205 begin
1210 begin
1220 {$ENDIF}
1222 initialization
1223 RegisterTypes;
1224 finalization
1225 UnRegisterTypes;
1229 {
1230 File Notes:
1232 -- TODOS ----------------------------------------------------
1233 - nothing now
1235 -- 0.77.1 ---------------------------------------------------
1236 - Fixed bug in ConvertBitmapToData causing images from GTK2 bitmaps
1237 to have swapped RB channels.
1238 - LCL: Removed GTK1 support (deprecated).
1240 -- 0.26.3 Changes/Bug Fixes ---------------------------------
1241 - Transparency of 8bit images (like loaded from 8bit PNG or GIF) is
1242 kept intact during conversion to TBitmap in ConvertDataToBitmap
1243 (32bit bitmap is created).
1245 -- 0.26.3 Changes/Bug Fixes ---------------------------------
1246 - Setting AlphaFormat property of TBitmap in ConvertDataToBitmap
1247 when using Delphi 2009+.
1248 - Fixed garbled LCL TBitmaps created by ConvertDataToBitmap
1249 in Mac OS X (Carbon).
1251 -- 0.26.1 Changes/Bug Fixes ---------------------------------
1252 - Added some more IFDEFs for Lazarus widget sets.
1253 - Removed CLX code.
1254 - GTK version of Unix DisplayImageData only used with LCL GTK so the
1255 the rest of the unit can be used with Qt or other LCL interfaces.
1256 - Fallback mechanism for DisplayImageDataOnDC, it may fail on occasions.
1257 - Changed file format conditional compilation to reflect changes
1258 in LINK symbols.
1259 - Lazarus 0.9.26 compatibility changes.
1261 -- 0.24.1 Changes/Bug Fixes ---------------------------------
1262 - Fixed wrong IFDEF causing that Imaging wouldn't compile in Lazarus
1263 with GTK2 target.
1264 - Added commnets with code for Lazarus rev. 11861+ regarding
1265 RawImage interface. Replace current code with that in comments
1266 if you use Lazarus from SVN. New RawImage interface will be used by
1267 default after next Lazarus release.
1269 -- 0.23 Changes/Bug Fixes -----------------------------------
1270 - Added TImagingGIF.
1272 -- 0.21 Changes/Bug Fixes -----------------------------------
1273 - Uses only high level interface now (except for saving options).
1274 - Slightly changed class hierarchy. TImagingGraphic is now only for loading
1275 and base class for savers is new TImagingGraphicForSave. Also
1276 TImagingGraphic is now registered with all supported file formats
1277 by TPicture's format support.
1279 -- 0.19 Changes/Bug Fixes -----------------------------------
1280 - added DisplayImage procedures (thanks to Paul Michell, modified)
1281 - removed RegisterTypes and UnRegisterTypes from interface section,
1282 they are called automatically
1283 - added procedures: ConvertImageToBitmap and ConvertBitmapToImage
1285 -- 0.17 Changes/Bug Fixes -----------------------------------
1286 - LCL data to bitmap conversion didnĀ“t work in Linux, fixed
1287 - added MNG file format
1288 - added JNG file format
1290 -- 0.15 Changes/Bug Fixes -----------------------------------
1291 - made it LCL compatible
1292 - made it CLX compatible
1293 - added all initial stuff
1294 }