Statistics
| Branch: | Tag: | Revision:

root / Imaging / ImagingComponents.pas @ 0:95bd93c28625

History | View | Annotate | Download (41.2 kB)

1
{
2
  $Id: ImagingComponents.pas 110 2007-11-18 21:23:59Z galfar $
3
  Vampyre Imaging Library
4
  by Marek Mauder 
5
  http://imaginglib.sourceforge.net
6
7
  The contents of this file are used with permission, subject to the Mozilla
8
  Public License Version 1.1 (the "License"); you may not use this file except
9
  in compliance with the License. You may obtain a copy of the License at
10
  http://www.mozilla.org/MPL/MPL-1.1.html
11
12
  Software distributed under the License is distributed on an "AS IS" basis,
13
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14
  the specific language governing rights and limitations under the License.
15
16
  Alternatively, the contents of this file may be used under the terms of the
17
  GNU Lesser General Public License (the  "LGPL License"), in which case the
18
  provisions of the LGPL License are applicable instead of those above.
19
  If you wish to allow use of your version of this file only under the terms
20
  of the LGPL License and not to allow others to use your version of this file
21
  under the MPL, indicate your decision by deleting  the provisions above and
22
  replace  them with the notice and other provisions required by the LGPL
23
  License.  If you do not delete the provisions above, a recipient may use
24
  your version of this file under either the MPL or the LGPL License.
25
26
  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html
27
}
28
29
{ This unit contains VCL/CLX/LCL TGraphic descendant which uses Imaging library
30
  for saving and loading.}
31
unit ImagingComponents;
32
33
{$I ImagingOptions.inc}
34
35
interface
36
37
uses
38
  SysUtils, Types, Classes,
39
{$IFDEF MSWINDOWS}
40
  Windows,
41
{$ENDIF}
42
{$IFDEF COMPONENT_SET_VCL}
43
  Graphics,
44
{$ENDIF}
45
{$IFDEF COMPONENT_SET_CLX}
46
  Qt,
47
  QGraphics,
48
{$ENDIF}
49
{$IFDEF COMPONENT_SET_LCL}
50
  InterfaceBase,
51
  GraphType,
52
  Graphics,
53
  LCLType,
54
  LCLIntf,
55
{$ENDIF}
56
  ImagingTypes, Imaging, ImagingClasses;
57
58
type
59
  { Graphic class which uses Imaging to load images.
60
    It has standard TBitmap class as ancestor and it can
61
    Assign also to/from TImageData structres and TBaseImage
62
    classes. For saving is uses inherited TBitmap methods.
63
    This class is automatically registered to TPicture for all
64
    file extensions supported by Imaging (useful only for loading).
65
    If you just want to load images in various formats you can use this
66
    class or simply use  TPicture.LoadFromXXX which will create this class
67
    automatically. For TGraphic class that saves with Imaging look
68
    at TImagingGraphicForSave class.}
69
  TImagingGraphic = class(TBitmap)
70
  protected
71
    procedure ReadDataFromStream(Stream: TStream); virtual;
72
    procedure AssignTo(Dest: TPersistent); override;
73
  public
74
    { Loads new image from the stream. It can load all image
75
      file formats supported by Imaging (and enabled of course)
76
      even though it is called by descendant class capable of
77
      saving only one file format.}
78
    procedure LoadFromStream(Stream: TStream); override;
79
    { Copies the image contained in Source to this graphic object.
80
      Supports also TBaseImage descendants from ImagingClasses unit. }
81
    procedure Assign(Source: TPersistent); override;
82
    { Copies the image contained in TBaseImage to this graphic object.}
83
    procedure AssignFromImage(Image: TBaseImage);
84
    { Copies the current image to TBaseImage object.}
85
    procedure AssignToImage(Image: TBaseImage);
86
    { Copies the image contained in TImageData structure to this graphic object.}
87
    procedure AssignFromImageData(const ImageData: TImageData);
88
    { Copies the current image to TImageData structure.}
89
    procedure AssignToImageData(var ImageData: TImageData);
90
  end;
91
92
  TImagingGraphicClass = class of TImagingGraphic;
93
94
  { Base class for file format specific TGraphic classes that use
95
    Imaging for saving. Each descendant class can load all file formats
96
    supported by Imaging but save only one format (TImagingBitmap
97
    for *.bmp, TImagingJpeg for *.jpg). Format specific classes also
98
    allow easy access to Imaging options that affect saving of files
99
    (they are properties here).}
100
  TImagingGraphicForSave = class(TImagingGraphic)
101
  protected
102
    FDefaultFileExt: string;
103
    FSavingFormat: TImageFormat;
104
    procedure WriteDataToStream(Stream: TStream); virtual;
105
  public
106
    constructor Create; override;
107
    { Saves the current image to the stream. It is saved in the
108
      file format according to the DefaultFileExt property.
109
      So each descendant class can save some other file format.}
110
    procedure SaveToStream(Stream: TStream); override;
111
    { Returns TImageFileFormat descendant for this graphic class.}
112
    class function GetFileFormat: TImageFileFormat; virtual; abstract;
113
  {$IFDEF COMPONENT_SET_LCL}
114
    { Returns file extensions of this graphic class.}
115
    class function GetFileExtensions: string; override;
116
    { Returns default MIME type of this graphic class.}
117
    function GetDefaultMimeType: string; override;
118
  {$ENDIF}
119
    { Default (the most common) file extension of this graphic class.}
120
    property DefaultFileExt: string read FDefaultFileExt;
121
  end;
122
123
  TImagingGraphicForSaveClass = class of TImagingGraphicForSave;
124
125
{$IFDEF LINK_BITMAP}
126
  { TImagingGraphic descendant for loading/saving Windows bitmaps.
127
    VCL/CLX/LCL all have native support for bitmaps so you might
128
    want to disable this class (although you can save bitmaps with
129
    RLE compression with this class).}
130
  TImagingBitmap = class(TImagingGraphicForSave)
131
  protected
132
    FUseRLE: Boolean;
133
  public
134
    constructor Create; override;
135
    procedure SaveToStream(Stream: TStream); override;
136
    class function GetFileFormat: TImageFileFormat; override;
137
    { See ImagingBitmapRLE option for details.}
138
    property UseRLE: Boolean read FUseRLE write FUseRLE;
139
  end;
140
{$ENDIF}
141
142
{$IFDEF LINK_JPEG}
143
  { TImagingGraphic descendant for loading/saving JPEG images.}
144
  TImagingJpeg = class(TImagingGraphicForSave)
145
  protected
146
    FQuality: LongInt;
147
    FProgressive: Boolean;
148
  public
149
    constructor Create; override;
150
    procedure SaveToStream(Stream: TStream); override;
151
    class function GetFileFormat: TImageFileFormat; override;
152
  {$IFDEF COMPONENT_SET_LCL}
153
    function GetDefaultMimeType: string; override;
154
  {$ENDIF}
155
    { See ImagingJpegQuality option for details.}
156
    property Quality: LongInt read FQuality write FQuality;
157
    { See ImagingJpegProgressive option for details.}
158
    property Progressive: Boolean read FProgressive write FProgressive;
159
  end;
160
{$ENDIF}
161
162
{$IFDEF LINK_PNG}
163
  { TImagingGraphic descendant for loading/saving PNG images.}
164
  TImagingPNG = class(TImagingGraphicForSave)
165
  protected
166
    FPreFilter: LongInt;
167
    FCompressLevel: LongInt;
168
  public
169
    constructor Create; override;
170
    procedure SaveToStream(Stream: TStream); override;
171
    class function GetFileFormat: TImageFileFormat; override;
172
    { See ImagingPNGPreFilter option for details.}
173
    property PreFilter: LongInt read FPreFilter write FPreFilter;
174
    { See ImagingPNGCompressLevel option for details.}
175
    property CompressLevel: LongInt read FCompressLevel write FCompressLevel;
176
  end;
177
{$ENDIF}
178
179
{$IFDEF LINK_GIF}
180
  { TImagingGraphic descendant for loading/saving GIF images.}
181
  TImagingGIF = class(TImagingGraphicForSave)
182
  public
183
    class function GetFileFormat: TImageFileFormat; override;
184
  end;
185
{$ENDIF}
186
187
{$IFDEF LINK_TARGA}
188
  { TImagingGraphic descendant for loading/saving Targa images.}
189
  TImagingTarga = class(TImagingGraphicForSave)
190
  protected
191
    FUseRLE: Boolean;
192
  public
193
    constructor Create; override;
194
    procedure SaveToStream(Stream: TStream); override;
195
    class function GetFileFormat: TImageFileFormat; override;
196
    { See ImagingTargaRLE option for details.}
197
    property UseRLE: Boolean read FUseRLE write FUseRLE;
198
  end;
199
{$ENDIF}
200
201
{$IFDEF LINK_DDS}
202
  { Compresssion type used when saving DDS files by TImagingDds.}
203
  TDDSCompresion = (dcNone, dcDXT1, dcDXT3, dcDXT5);
204
205
  { TImagingGraphic descendant for loading/saving DDS images.}
206
  TImagingDDS = class(TImagingGraphicForSave)
207
  protected
208
    FCompression: TDDSCompresion;
209
  public
210
    constructor Create; override;
211
    procedure SaveToStream(Stream: TStream); override;
212
    class function GetFileFormat: TImageFileFormat; override;
213
    { You can choose compression type used when saving DDS file.
214
      dcNone means that file will be saved in the current bitmaps pixel format.}
215
    property Compression: TDDSCompresion read FCompression write FCompression;
216
  end;
217
{$ENDIF}
218
219
{$IFDEF LINK_MNG}
220
  { TImagingGraphic descendant for loading/saving MNG images.}
221
  TImagingMNG = class(TImagingGraphicForSave)
222
  protected
223
    FLossyCompression: Boolean;
224
    FLossyAlpha: Boolean;
225
    FPreFilter: LongInt;
226
    FCompressLevel: LongInt;
227
    FQuality: LongInt;
228
    FProgressive: Boolean;
229
  public
230
    constructor Create; override;
231
    procedure SaveToStream(Stream: TStream); override;
232
    class function GetFileFormat: TImageFileFormat; override;
233
  {$IFDEF COMPONENT_SET_LCL}
234
    function GetDefaultMimeType: string; override;
235
  {$ENDIF}
236
    { See ImagingMNGLossyCompression option for details.}
237
    property LossyCompression: Boolean read FLossyCompression write FLossyCompression;
238
    { See ImagingMNGLossyAlpha option for details.}
239
    property LossyAlpha: Boolean read FLossyAlpha write FLossyAlpha;
240
    { See ImagingMNGPreFilter option for details.}
241
    property PreFilter: LongInt read FPreFilter write FPreFilter;
242
    { See ImagingMNGCompressLevel option for details.}
243
    property CompressLevel: LongInt read FCompressLevel write FCompressLevel;
244
    { See ImagingMNGQuality option for details.}
245
    property Quality: LongInt read FQuality write FQuality;
246
    { See ImagingMNGProgressive option for details.}
247
    property Progressive: Boolean read FProgressive write FProgressive;
248
  end;
249
{$ENDIF}
250
251
{$IFDEF LINK_JNG}
252
  { TImagingGraphic descendant for loading/saving JNG images.}
253
  TImagingJNG = class(TImagingGraphicForSave)
254
  protected
255
    FLossyAlpha: Boolean;
256
    FAlphaPreFilter: LongInt;
257
    FAlphaCompressLevel: LongInt;
258
    FQuality: LongInt;
259
    FProgressive: Boolean;
260
  public
261
    constructor Create; override;
262
    procedure SaveToStream(Stream: TStream); override;
263
    class function GetFileFormat: TImageFileFormat; override;
264
    { See ImagingJNGLossyAlpha option for details.}
265
    property LossyAlpha: Boolean read FLossyAlpha write FLossyAlpha;
266
    { See ImagingJNGPreFilter option for details.}
267
    property AlphaPreFilter: LongInt read FAlphaPreFilter write FAlphaPreFilter;
268
    { See ImagingJNGCompressLevel option for details.}
269
    property AlphaCompressLevel: LongInt read FAlphaCompressLevel write FAlphaCompressLevel;
270
    { See ImagingJNGQuality option for details.}
271
    property Quality: LongInt read FQuality write FQuality;
272
    { See ImagingJNGProgressive option for details.}
273
    property Progressive: Boolean read FProgressive write FProgressive;
274
  end;
275
{$ENDIF}
276
277
{ Returns bitmap pixel format with the closest match with given data format.}
278
function DataFormatToPixelFormat(Format: TImageFormat): TPixelFormat;
279
{ Returns data format with closest match with given bitmap pixel format.}
280
function PixelFormatToDataFormat(Format: TPixelFormat): TImageFormat;
281
282
{ Converts TImageData structure to VCL/CLX/LCL bitmap.}
283
procedure ConvertDataToBitmap(const Data: TImageData; Bitmap: TBitmap);
284
{ Converts VCL/CLX/LCL bitmap to TImageData structure.}
285
procedure ConvertBitmapToData(Bitmap: TBitmap; var Data: TImageData);
286
{ Converts TBaseImage instance to VCL/CLX/LCL bitmap.}
287
procedure ConvertImageToBitmap(Image: TBaseImage; Bitmap: TBitmap);
288
{ Converts VCL/CLX/LCL bitmap to TBaseImage. Image must exist before
289
  procedure is called. It overwrites its current image data.
290
  When Image is TMultiImage only the current image level is overwritten.}
291
procedure ConvertBitmapToImage(Bitmap: TBitmap; Image: TBaseImage);
292
293
{ Displays image stored in TImageData structure onto TCanvas. This procedure
294
  draws image without converting from Imaging format to TBitmap.
295
  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
296
  when you want displaying images that change frequently (because converting to
297
  TBitmap by ConvertImageDataToBitmap is generally slow). Dest and Src
298
  rectangles represent coordinates in the form (X1, Y1, X2, Y2).}
299
procedure DisplayImageData(DstCanvas: TCanvas; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
300
{ Displays image onto TCanvas at position [DstX, DstY]. This procedure
301
  draws image without converting from Imaging format to TBitmap.
302
  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
303
  when you want displaying images that change frequently (because converting to
304
  TBitmap by ConvertImageDataToBitmap is generally slow).}
305
procedure DisplayImage(DstCanvas: TCanvas; DstX, DstY: LongInt; Image: TBaseImage); overload;
306
{ Displays image onto TCanvas to rectangle DstRect. This procedure
307
  draws image without converting from Imaging format to TBitmap.
308
  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
309
  when you want displaying images that change frequently (because converting to
310
  TBitmap by ConvertImageDataToBitmap is generally slow).}
311
procedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage); overload;
312
{ Displays part of the image specified by SrcRect onto TCanvas to rectangle DstRect.
313
  This procedure draws image without converting from Imaging format to TBitmap.
314
  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this
315
  when you want displaying images that change frequently (because converting to
316
  TBitmap by ConvertImageDataToBitmap is generally slow).}
317
procedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage; const SrcRect: TRect); overload;
318
319
{$IFDEF MSWINDOWS}
320
{ Displays image stored in TImageData structure onto Windows device context.
321
  Behaviour is the same as of DisplayImageData.}
322
procedure DisplayImageDataOnDC(DC: HDC; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
323
{$ENDIF}
324
325
implementation
326
327
uses
328
{$IF Defined(UNIX) and Defined(COMPONENT_SET_LCL)}
329
  {$IFDEF LCLGTK2}
330
    GLib2, GDK2, GTK2, GTKDef, GTKProc,
331
  {$ELSE}
332
    GDK, GTK, GTKDef, GTKProc,
333
  {$ENDIF}
334
{$IFEND}
335
{$IFDEF LINK_BITMAP}
336
  ImagingBitmap,
337
{$ENDIF}
338
{$IFDEF LINK_JPEG}
339
  ImagingJpeg,
340
{$ENDIF}
341
{$IFDEF LINK_GIF}
342
  ImagingGif,
343
{$ENDIF}
344
{$IFDEF LINK_TARGA}
345
  ImagingTarga,
346
{$ENDIF}
347
{$IFDEF LINK_DDS}
348
  ImagingDds,
349
{$ENDIF}
350
{$IF Defined(LINK_PNG) or Defined(LINK_MNG) or Defined(LINK_JNG)}
351
  ImagingNetworkGraphics,
352
{$IFEND}
353
  ImagingUtility;
354
355
resourcestring
356
  SBadFormatDataToBitmap = 'Cannot find compatible bitmap format for image %s';
357
  SBadFormatBitmapToData = 'Cannot find compatible data format for bitmap %p';
358
  SBadFormatDisplay = 'Unsupported image format passed';
359
  SImagingGraphicName = 'Imaging Graphic AllInOne';
360
361
{ Registers types to VCL/CLX/LCL.}
362
procedure RegisterTypes;
363
var
364
  I: LongInt;
365
366
  procedure RegisterFileFormatAllInOne(Format: TImageFileFormat);
367
  var
368
    I: LongInt;
369
  begin
370
    for I := 0 to Format.Extensions.Count - 1 do
371
      TPicture.RegisterFileFormat(Format.Extensions[I], SImagingGraphicName,
372
        TImagingGraphic);
373
  end;
374
375
  procedure RegisterFileFormat(AClass: TImagingGraphicForSaveClass);
376
  var
377
    I: LongInt;
378
  begin
379
    for I := 0 to AClass.GetFileFormat.Extensions.Count - 1 do
380
      TPicture.RegisterFileFormat(AClass.GetFileFormat.Extensions[I],
381
        AClass.GetFileFormat.Name, AClass);
382
  end;
383
384
begin
385
  for I := Imaging.GetFileFormatCount - 1 downto 0 do
386
    RegisterFileFormatAllInOne(Imaging.GetFileFormatAtIndex(I));
387
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingGraphic);{$ENDIF}
388
389
{$IFDEF LINK_TARGA}
390
  RegisterFileFormat(TImagingTarga);
391
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingTarga);{$ENDIF}
392
{$ENDIF}
393
{$IFDEF LINK_DDS}
394
  RegisterFileFormat(TImagingDDS);
395
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingDDS);{$ENDIF}
396
{$ENDIF}
397
{$IFDEF LINK_JNG}
398
  RegisterFileFormat(TImagingJNG);
399
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingJNG);{$ENDIF}
400
{$ENDIF}
401
{$IFDEF LINK_MNG}
402
  RegisterFileFormat(TImagingMNG);
403
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingMNG);{$ENDIF}
404
{$ENDIF}
405
{$IFDEF LINK_GIF}
406
  RegisterFileFormat(TImagingGIF);
407
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingGIF);{$ENDIF}
408
{$ENDIF}
409
{$IFDEF LINK_PNG}
410
  {$IFDEF COMPONENT_SET_LCL}
411
    // Unregister Lazarus? default PNG loader which crashes on some PNG files
412
    TPicture.UnregisterGraphicClass(TPortableNetworkGraphic);
413
  {$ENDIF}
414
  RegisterFileFormat(TImagingPNG);
415
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingPNG);{$ENDIF}
416
{$ENDIF}
417
{$IFDEF LINK_JPEG}
418
  RegisterFileFormat(TImagingJpeg);
419
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingJpeg);{$ENDIF}
420
{$ENDIF}
421
{$IFDEF LINK_BITMAP}
422
  RegisterFileFormat(TImagingBitmap);
423
  {$IFNDEF COMPONENT_SET_CLX}Classes.RegisterClass(TImagingBitmap);{$ENDIF}
424
{$ENDIF}   
425
end;
426
427
{ Unregisters types from VCL/CLX/LCL.}
428
procedure UnRegisterTypes;
429
begin
430
{$IFDEF LINK_BITMAP}
431
  TPicture.UnregisterGraphicClass(TImagingBitmap);
432
  {$IFNDEF COMPONENT_SET_CLX}Classes.UnRegisterClass(TImagingBitmap);{$ENDIF}
433
{$ENDIF}
434
{$IFDEF LINK_JPEG}
435
  TPicture.UnregisterGraphicClass(TImagingJpeg);
436
  {$IFNDEF COMPONENT_SET_CLX}Classes.UnRegisterClass(TImagingJpeg);{$ENDIF}
437
{$ENDIF}
438
{$IFDEF LINK_PNG}
439
  TPicture.UnregisterGraphicClass(TImagingPNG);
440
  {$IFNDEF COMPONENT_SET_CLX}Classes.UnRegisterClass(TImagingPNG);{$ENDIF}
441
{$ENDIF}
442
{$IFDEF LINK_GIF}
443
  TPicture.UnregisterGraphicClass(TImagingGIF);
444
  {$IFNDEF COMPONENT_SET_CLX}Classes.UnRegisterClass(TImagingGIF);{$ENDIF}
445
{$ENDIF}
446
{$IFDEF LINK_TARGA}
447
  TPicture.UnregisterGraphicClass(TImagingTarga);
448
  {$IFNDEF COMPONENT_SET_CLX}Classes.UnRegisterClass(TImagingTarga);{$ENDIF}
449
{$ENDIF}
450
{$IFDEF LINK_DDS}
451
  TPicture.UnregisterGraphicClass(TImagingDDS);
452
  {$IFNDEF COMPONENT_SET_CLX}Classes.UnRegisterClass(TImagingDDS);{$ENDIF}
453
{$ENDIF}
454
  TPicture.UnregisterGraphicClass(TImagingGraphic);
455
  {$IFNDEF COMPONENT_SET_CLX}Classes.UnRegisterClass(TImagingGraphic);{$ENDIF}
456
end;
457
458
function DataFormatToPixelFormat(Format: TImageFormat): TPixelFormat;
459
begin
460
  case Format of
461
{$IFNDEF COMPONENT_SET_LCL}
462
    ifIndex8: Result := pf8bit;
463
{$ENDIF}
464
{$IF (not Defined(COMPONENT_SET_CLX)) and (not Defined(COMPONENT_SET_LCL))}
465
    ifR5G6B5: Result := pf16bit;
466
    ifR8G8B8: Result := pf24bit;
467
{$IFEND}
468
    ifA8R8G8B8,
469
    ifX8R8G8B8: Result := pf32bit;
470
  else
471
    Result := pfCustom;
472
  end;
473
end;
474
475
function PixelFormatToDataFormat(Format: TPixelFormat): TImageFormat;
476
begin
477
  case Format of
478
    pf8bit: Result := ifIndex8;
479
{$IFNDEF COMPONENT_SET_CLX}
480
    pf15bit: Result := ifA1R5G5B5;
481
    pf16bit: Result := ifR5G6B5;
482
    pf24bit: Result := ifR8G8B8;
483
{$ENDIF}
484
    pf32bit: Result := ifA8R8G8B8;
485
  else
486
    Result := ifUnknown;
487
  end;
488
end;
489
490
procedure ConvertDataToBitmap(const Data: TImageData; Bitmap: TBitmap);
491
var
492
  I, LineBytes: LongInt;
493
  PF: TPixelFormat;
494
  Info: TImageFormatInfo;
495
  WorkData: TImageData;
496
{$IFDEF COMPONENT_SET_VCL}
497
  LogPalette: TMaxLogPalette;
498
{$ENDIF}
499
{$IFDEF COMPONENT_SET_CLX}
500
  ColorTable: PPalette32;
501
{$ENDIF}
502
{$IFDEF COMPONENT_SET_LCL}
503
  RawImage: TRawImage;
504
  ImgHandle, ImgMaskHandle: HBitmap;
505
{$ENDIF}
506
begin
507
  PF := DataFormatToPixelFormat(Data.Format);
508
  GetImageFormatInfo(Data.Format, Info);
509
  if PF = pfCustom then
510
  begin
511
    // Convert from formats not supported by Graphics unit
512
    Imaging.InitImage(WorkData);
513
    Imaging.CloneImage(Data, WorkData);
514
    if Info.IsFloatingPoint or Info.HasAlphaChannel or Info.IsSpecial then
515
      Imaging.ConvertImage(WorkData, ifA8R8G8B8)
516
    else
517
{$IFNDEF COMPONENT_SET_LCL}
518
      if Info.IsIndexed or Info.HasGrayChannel then
519
        Imaging.ConvertImage(WorkData, ifIndex8)
520
      else
521
{$ENDIF}
522
{$IF (not Defined(COMPONENT_SET_CLX)) and (not Defined(COMPONENT_SET_LCL))}
523
        if Info.UsePixelFormat then
524
          Imaging.ConvertImage(WorkData, ifR5G6B5)
525
        else
526
          Imaging.ConvertImage(WorkData, ifR8G8B8);
527
{$ELSE}
528
        Imaging.ConvertImage(WorkData, ifA8R8G8B8);
529
{$IFEND}
530
531
    PF := DataFormatToPixelFormat(WorkData.Format);
532
    GetImageFormatInfo(WorkData.Format, Info);
533
  end
534
  else
535
    WorkData := Data;
536
    
537
  if PF = pfCustom then
538
    RaiseImaging(SBadFormatDataToBitmap, [ImageToStr(WorkData)]);
539
      
540
  LineBytes := WorkData.Width * Info.BytesPerPixel;
541
542
{$IFDEF COMPONENT_SET_VCL}
543
  Bitmap.Width := WorkData.Width;
544
  Bitmap.Height := WorkData.Height;
545
  Bitmap.PixelFormat := PF;
546
547
  if (PF = pf8bit) and (WorkData.Palette <> nil) then
548
  begin
549
    // Copy palette, this must be done before copying bits
550
    FillChar(LogPalette, SizeOf(LogPalette), 0);
551
    LogPalette.palVersion := $300;
552
    LogPalette.palNumEntries := Info.PaletteEntries;
553
    for I := 0 to Info.PaletteEntries - 1 do
554
    with LogPalette do
555
    begin
556
      palPalEntry[I].peRed := WorkData.Palette[I].R;
557
      palPalEntry[I].peGreen := WorkData.Palette[I].G;
558
      palPalEntry[I].peBlue := WorkData.Palette[I].B;
559
    end;
560
    Bitmap.Palette := CreatePalette(PLogPalette(@LogPalette)^);
561
  end;
562
  // Copy scanlines
563
  for I := 0 to WorkData.Height - 1 do
564
    Move(PByteArray(WorkData.Bits)[I * LineBytes], Bitmap.Scanline[I]^, LineBytes);
565
{$ENDIF}
566
{$IFDEF COMPONENT_SET_CLX}
567
  Bitmap.Width := WorkData.Width;
568
  Bitmap.Height := WorkData.Height;
569
  Bitmap.PixelFormat := PF;
570
571
  if (PF = pf8bit) and (WorkData.Palette <> nil) then
572
  begin
573
    // Copy palette
574
    ColorTable := Bitmap.ColorTable;
575
    for I := 0 to Info.PaletteEntries - 1 do
576
    with ColorTable[I] do
577
    begin
578
      R := WorkData.Palette[I].R;
579
      G := WorkData.Palette[I].G;
580
      B := WorkData.Palette[I].B;
581
    end;
582
  end;
583
  // Copy scanlines
584
  for I := 0 to WorkData.Height - 1 do
585
    Move(PByteArray(WorkData.Bits)[I * LineBytes], Bitmap.Scanline[I]^, LineBytes);
586
{$ENDIF}
587
{$IFDEF COMPONENT_SET_LCL}
588
  // Create 32bit raw image from image data
589
  FillChar(RawImage, SizeOf(RawImage), 0);
590
  with RawImage.Description do
591
  begin
592
    Width := WorkData.Width;
593
    Height := WorkData.Height;
594
    BitsPerPixel := Info.BytesPerPixel * 8;
595
    Format := ricfRGBA;
596
    LineEnd := rileByteBoundary;
597
    BitOrder := riboBitsInOrder;
598
    ByteOrder := riboLSBFirst;
599
    LineOrder := riloTopToBottom;
600
    AlphaPrec := 8;
601
    RedPrec := 8;
602
    GreenPrec := 8;
603
    BluePrec := 8;
604
    AlphaShift := 24;
605
    RedShift := 16;
606
    GreenShift := 8;
607
    BlueShift := 0;
608
    Depth := 24;
609
  end;
610
  RawImage.Data := WorkData.Bits;
611
  RawImage.DataSize := WorkData.Size;
612
613
  // Create bitmap from raw image
614
  { If you get complitation error here upgrade to Lazarus 0.9.24+ }
615
  if RawImage_CreateBitmaps(RawImage, ImgHandle, ImgMaskHandle, False) then
616
  begin
617
    Bitmap.Handle := ImgHandle;
618
    Bitmap.MaskHandle := ImgMaskHandle;
619
  end;
620
{$ENDIF}
621
  if WorkData.Bits <> Data.Bits then
622
    Imaging.FreeImage(WorkData);
623
end;
624
625
procedure ConvertBitmapToData(Bitmap: TBitmap; var Data: TImageData);
626
var
627
  I, LineBytes: LongInt;
628
  Format: TImageFormat;
629
  Info: TImageFormatInfo;
630
{$IFDEF COMPONENT_SET_VCL}
631
  Colors: Word;
632
  LogPalette: TMaxLogPalette;
633
{$ENDIF}
634
{$IFDEF COMPONENT_SET_CLX}
635
  ColorTable: PPalette32;
636
{$ENDIF}
637
{$IFDEF COMPONENT_SET_LCL}
638
  RawImage: TRawImage;
639
  LineLazBytes: LongInt;
640
{$ENDIF}
641
begin
642
{$IFDEF COMPONENT_SET_LCL}
643
  // In the current Lazarus 0.9.10 Bitmap.PixelFormat property is useless.
644
  // We cannot change bitmap's format by changing it (it will just release
645
  // old image but not convert it to new format) nor we can determine bitmaps's
646
  // current format (it is usually set to pfDevice). So bitmap's format is obtained
647
  // trough RawImage api and cannot be changed to mirror some Imaging format
648
  // (so formats with no coresponding Imaging format cannot be saved now).
649
650
  { If you get complitation error here upgrade to Lazarus 0.9.24+ }
651
  if RawImage_DescriptionFromBitmap(Bitmap.Handle, RawImage.Description) then
652
    case RawImage.Description.BitsPerPixel of
653
      8: Format := ifIndex8;
654
      16:
655
        if RawImage.Description.Depth = 15 then
656
          Format := ifA1R5G5B5
657
        else
658
          Format := ifR5G6B5;
659
      24: Format := ifR8G8B8;
660
      32: Format := ifA8R8G8B8;
661
      48: Format := ifR16G16B16;
662
      64: Format := ifA16R16G16B16;
663
    else
664
      Format := ifUnknown;
665
    end;
666
{$ELSE}
667
  Format := PixelFormatToDataFormat(Bitmap.PixelFormat);
668
  if Format = ifUnknown then
669
  begin
670
    // Convert from formats not supported by Imaging (1/4 bit)
671
    if Bitmap.PixelFormat < pf8bit then
672
       Bitmap.PixelFormat := pf8bit
673
    else
674
      Bitmap.PixelFormat := pf32bit;
675
    Format := PixelFormatToDataFormat(Bitmap.PixelFormat);
676
  end;
677
{$ENDIF}
678
679
  if Format = ifUnknown then
680
    RaiseImaging(SBadFormatBitmapToData, []);
681
682
  Imaging.NewImage(Bitmap.Width, Bitmap.Height, Format, Data);
683
  GetImageFormatInfo(Data.Format, Info);
684
  LineBytes := Data.Width * Info.BytesPerPixel;
685
686
{$IFDEF COMPONENT_SET_VCL}
687
  if (Format = ifIndex8) and (GetObject(Bitmap.Palette, SizeOf(Colors),
688
    @Colors) <> 0) then
689
  begin
690
    // Copy palette
691
    GetPaletteEntries(Bitmap.Palette, 0, Colors, LogPalette.palPalEntry);
692
    if Colors > Info.PaletteEntries  then
693
      Colors := Info.PaletteEntries;
694
    for I := 0 to Colors - 1 do
695
    with LogPalette do
696
    begin
697
      Data.Palette[I].A := $FF;
698
      Data.Palette[I].R := palPalEntry[I].peRed;
699
      Data.Palette[I].G := palPalEntry[I].peGreen;
700
      Data.Palette[I].B := palPalEntry[I].peBlue;
701
    end;
702
  end;
703
  // Copy scanlines
704
  for I := 0 to Data.Height - 1 do
705
    Move(Bitmap.ScanLine[I]^, PByteArray(Data.Bits)[I * LineBytes], LineBytes);
706
{$ENDIF}
707
{$IFDEF COMPONENT_SET_CLX}
708
  if Format = ifIndex8 then
709
  begin
710
    // Copy palette
711
    ColorTable := Bitmap.ColorTable;
712
    for I := 0 to Info.PaletteEntries - 1 do
713
    with ColorTable[I] do
714
    begin
715
      Data.Palette[I].A := $FF;
716
      Data.Palette[I].R := R;
717
      Data.Palette[I].G := G;
718
      Data.Palette[I].B := B;
719
    end;
720
  end;
721
  // Copy scanlines
722
  for I := 0 to Data.Height - 1 do
723
    Move(Bitmap.ScanLine[I]^, PByteArray(Data.Bits)[I * LineBytes], LineBytes);
724
{$ENDIF}
725
{$IFDEF COMPONENT_SET_LCL}
726
  // Get raw image from bitmap (mask handle must be 0 or expect violations)
727
  { If you get complitation error here upgrade to Lazarus 0.9.24+ }
728
  if RawImage_FromBitmap(RawImage, Bitmap.Handle, 0, Classes.Rect(0, 0, Data.Width, Data.Height)) then
729
  begin
730
    LineLazBytes := GetBytesPerLine(Data.Width, RawImage.Description.BitsPerPixel,
731
      RawImage.Description.LineEnd);
732
    // Copy scanlines
733
    for I := 0 to Data.Height - 1 do
734
      Move(PByteArray(RawImage.Data)[I * LineLazBytes],
735
        PByteArray(Data.Bits)[I * LineBytes], LineBytes);
736
    { If you get complitation error here upgrade to Lazarus 0.9.24+ }
737
    RawImage.FreeData;
738
  end;
739
{$ENDIF}
740
end;
741
742
procedure ConvertImageToBitmap(Image: TBaseImage; Bitmap: TBitmap);
743
begin
744
  ConvertDataToBitmap(Image.ImageDataPointer^, Bitmap);
745
end;
746
747
procedure ConvertBitmapToImage(Bitmap: TBitmap; Image: TBaseImage);
748
begin
749
  ConvertBitmapToData(Bitmap, Image.ImageDataPointer^);
750
end;
751
752
{$IFDEF MSWINDOWS}
753
procedure DisplayImageDataOnDC(DC: HDC; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
754
var
755
  OldMode: Integer;
756
  BitmapInfo: Windows.TBitmapInfo;
757
begin
758
  if TestImage(ImageData) then
759
  begin
760
    Assert(ImageData.Format in [ifA8R8G8B8, ifX8R8G8B8], SBadFormatDisplay);
761
    OldMode := Windows.SetStretchBltMode(DC, COLORONCOLOR);
762
763
    FillChar(BitmapInfo, SizeOf(BitmapInfo), 0);
764
    with BitmapInfo.bmiHeader do
765
    begin
766
      biSize := SizeOf(TBitmapInfoHeader);
767
      biPlanes := 1;
768
      biBitCount := 32;
769
      biCompression := BI_RGB;
770
      biWidth := ImageData.Width;
771
      biHeight := -ImageData.Height;
772
      biSizeImage := ImageData.Size;
773
      biXPelsPerMeter := 0;
774
      biYPelsPerMeter := 0;
775
      biClrUsed := 0;
776
      biClrImportant := 0;
777
    end;
778
779
    try
780
      with SrcRect, ImageData do
781
        Windows.StretchDIBits(DC, DstRect.Left, DstRect.Top,
782
          DstRect.Right - DstRect.Left, DstRect.Bottom - DstRect.Top, Left,
783
          Top, Right - Left, Bottom - Top, Bits, BitmapInfo, DIB_RGB_COLORS, SRCCOPY);
784
    finally
785
      Windows.SetStretchBltMode(DC, OldMode);
786
    end;
787
  end;  
788
end;
789
{$ENDIF}
790
791
procedure DisplayImageData(DstCanvas: TCanvas; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);
792
{$IF Defined(MSWINDOWS) and not Defined(COMPONENT_SET_CLX)}
793
begin
794
  DisplayImageDataOnDC(DstCanvas.Handle, DstRect, ImageData, SrcRect);
795
end;
796
{$ELSEIF Defined(COMPONENT_SET_CLX)}
797
var
798
  Bitmap: TBitmap;
799
  //Handle: LongWord;
800
begin
801
  (*
802
  // It would be nice if this worked:
803
  DstCanvas.Start;
804
  Handle := QPainter_handle(DstCanvas.Handle);
805
  {$IFDEF MSWINDOWS}
806
  DisplayImageDataOnDC(Handle, DstRect, ImageData, SrcRect);
807
  {$ELSE}
808
  DisplayImageDataOnX(Handle, DstRect, ImageData, SrcRect);
809
  {$ENDIF}
810
  DstCanvas.Stop;
811
  *)
812
  Bitmap := TBitmap.Create;
813
  try
814
    ConvertDataToBitmap(ImageData, Bitmap);
815
    DstCanvas.CopyRect(DstRect, Bitmap.Canvas, SrcRect);
816
  finally
817
    Bitmap.Free;
818
  end;  
819
end;
820
{$ELSEIF Defined(UNIX) and Defined(COMPONENT_SET_LCL)}
821
822
  procedure GDKDrawBitmap(Dest: HDC; DstX, DstY: Integer; SrcX, SrcY,
823
    SrcWidth, SrcHeight: Integer; ImageData: TImageData);
824
  var
825
    P: TPoint;
826
  begin
827
    P := TGtkDeviceContext(Dest).Offset;
828
    Inc(DstX, P.X);
829
    Inc(DstY, P.Y);
830
    gdk_draw_rgb_32_image(TGtkDeviceContext(Dest).Drawable, TGtkDeviceContext(Dest).GC,
831
      DstX, DstY, SrcWidth, SrcHeight, GDK_RGB_DITHER_NONE,
832
      @PLongWordArray(ImageData.Bits)[SrcY * ImageData.Width + SrcX], ImageData.Width * 4);
833
  end;
834
  
835
var
836
  DisplayImage: TImageData;
837
  NewWidth, NewHeight: Integer;
838
  SrcBounds, DstBounds, DstClip: TRect;
839
begin
840
  if TestImage(ImageData) then
841
  begin
842
    Assert(ImageData.Format in [ifA8R8G8B8, ifX8R8G8B8], SBadFormatDisplay);
843
    InitImage(DisplayImage);
844
845
    SrcBounds := RectToBounds(SrcRect);
846
    DstBounds := RectToBounds(DstRect);
847
    WidgetSet.GetClipBox(DstCanvas.Handle, @DstClip);
848
849
    ClipStretchBounds(SrcBounds.Left, SrcBounds.Top, SrcBounds.Right, SrcBounds.Bottom,
850
      DstBounds.Left, DstBounds.Top, DstBounds.Right, DstBounds.Bottom, ImageData.Width,
851
      ImageData.Height, DstClip);
852
853
    NewWidth := DstBounds.Right;
854
    NewHeight := DstBounds.Bottom;
855
856
    if (NewWidth > 0) and (NewHeight > 0) then
857
    begin
858
      if (SrcBounds.Right = NewWidth) and (SrcBounds.Bottom = NewHeight) then
859
      try
860
        CloneImage(ImageData, DisplayImage);
861
        // Swap R-B channels for GTK display compatability!
862
        SwapChannels(DisplayImage, ChannelRed, ChannelBlue);
863
        GDKDrawBitmap(DstCanvas.Handle, DstBounds.Left, DstBounds.Top,
864
          SrcBounds.Left, SrcBounds.Top, NewWidth, NewHeight, DisplayImage);
865
      finally
866
        FreeImage(DisplayImage);
867
      end
868
      else
869
      try
870
        // Create new image with desired dimensions
871
        NewImage(NewWidth, NewHeight, ImageData.Format, DisplayImage);
872
        // Stretch pixels from old image to new one  TResizeFilter = (rfNearest, rfBilinear, rfBicubic);
873
        StretchRect(ImageData, SrcBounds.Left, SrcBounds.Top, SrcBounds.Right,
874
          SrcBounds.Bottom, DisplayImage, 0, 0, NewWidth, NewHeight, rfNearest);
875
        // Swap R-B channels for GTK display compatability!
876
        SwapChannels(DisplayImage, ChannelRed, ChannelBlue);
877
        GDKDrawBitmap(DstCanvas.Handle, DstBounds.Left, DstBounds.Top, 0, 0,
878
          NewWidth, NewHeight, DisplayImage);
879
       finally
880
        FreeImage(DisplayImage);
881
      end
882
    end;
883
  end;
884
end;
885
{$IFEND}
886
887
procedure DisplayImage(DstCanvas: TCanvas; DstX, DstY: LongInt; Image: TBaseImage);
888
begin
889
  DisplayImageData(DstCanvas, BoundsToRect(DstX, DstY, Image.Width, Image.Height),
890
    Image.ImageDataPointer^, Image.BoundsRect);
891
end;
892
893
procedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage);
894
begin
895
  DisplayImageData(DstCanvas, DstRect, Image.ImageDataPointer^, Image.BoundsRect);
896
end;
897
898
procedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage; const SrcRect: TRect);
899
begin
900
  DisplayImageData(DstCanvas, DstRect, Image.ImageDataPointer^, SrcRect);
901
end;
902
903
904
{ TImagingGraphic class implementation }
905
906
procedure TImagingGraphic.LoadFromStream(Stream: TStream);
907
begin
908
  ReadDataFromStream(Stream);
909
end;
910
911
procedure TImagingGraphic.ReadDataFromStream(Stream: TStream);
912
var
913
  Image: TSingleImage;
914
begin
915
  Image := TSingleImage.Create;
916
  try
917
    Image.LoadFromStream(Stream);
918
    Assign(Image);
919
  finally
920
    Image.Free;
921
  end;
922
end;
923
924
procedure TImagingGraphic.AssignTo(Dest: TPersistent);
925
var
926
  Arr: TDynImageDataArray;
927
begin
928
  if Dest is TSingleImage then
929
  begin
930
    AssignToImage(TSingleImage(Dest))
931
  end
932
  else if Dest is TMultiImage then
933
  begin
934
    SetLength(Arr, 1);
935
    AssignToImageData(Arr[0]);
936
    TMultiImage(Dest).CreateFromArray(Arr);
937
    Imaging.FreeImagesInArray(Arr);
938
  end
939
  else
940
    inherited AssignTo(Dest);
941
end;
942
943
procedure TImagingGraphic.Assign(Source: TPersistent);
944
begin
945
  if Source is TBaseImage then
946
    AssignFromImage(TBaseImage(Source))
947
  else
948
    inherited Assign(Source);
949
end;
950
951
procedure TImagingGraphic.AssignFromImage(Image: TBaseImage);
952
begin
953
  if (Image <> nil) and Image.Valid then
954
    AssignFromImageData(Image.ImageDataPointer^);
955
end;
956
957
procedure TImagingGraphic.AssignToImage(Image: TBaseImage);
958
begin
959
  if (Image <> nil) and (Image.ImageDataPointer <> nil) then
960
    AssignToImageData(Image.ImageDataPointer^);
961
end;
962
963
procedure TImagingGraphic.AssignFromImageData(const ImageData: TImageData);
964
begin
965
  if Imaging.TestImage(ImageData) then
966
    ConvertDataToBitmap(ImageData, Self);
967
end;
968
969
procedure TImagingGraphic.AssignToImageData(var ImageData: TImageData);
970
begin
971
  Imaging.FreeImage(ImageData);
972
  ConvertBitmapToData(Self, ImageData);
973
end;
974
975
976
{ TImagingGraphicForSave class implementation }
977
978
constructor TImagingGraphicForSave.Create;
979
begin
980
  inherited Create;
981
  FDefaultFileExt := GetFileFormat.Extensions[0];
982
  FSavingFormat := ifUnknown;
983
  GetFileFormat.CheckOptionsValidity;
984
end;
985
986
procedure TImagingGraphicForSave.WriteDataToStream(Stream: TStream);
987
var
988
  Image: TSingleImage;
989
begin
990
  if FDefaultFileExt <> '' then
991
  begin
992
    Image := TSingleImage.Create;
993
    try
994
      Image.Assign(Self);
995
      if FSavingFormat <> ifUnknown then
996
        Image.Format := FSavingFormat;
997
      Image.SaveToStream(FDefaultFileExt, Stream);
998
    finally
999
      Image.Free;
1000
    end;
1001
  end;
1002
end;
1003
1004
procedure TImagingGraphicForSave.SaveToStream(Stream: TStream);
1005
begin
1006
  WriteDataToStream(Stream);
1007
end;
1008
1009
{$IFDEF COMPONENT_SET_LCL}
1010
class function TImagingGraphicForSave.GetFileExtensions: string;
1011
begin
1012
  Result := StringReplace(GetFileFormat.Extensions.CommaText, ',', ';', [rfReplaceAll]);
1013
end;
1014
1015
function TImagingGraphicForSave.GetDefaultMimeType: string;
1016
begin
1017
  Result := 'image/' + FDefaultFileExt;
1018
end;
1019
{$ENDIF}
1020
1021
{$IFDEF LINK_BITMAP}
1022
1023
{ TImagingBitmap class implementation }
1024
1025
constructor TImagingBitmap.Create;
1026
begin
1027
  inherited Create;
1028
  FUseRLE := (GetFileFormat as TBitmapFileFormat).UseRLE;
1029
end;
1030
1031
class function TImagingBitmap.GetFileFormat: TImageFileFormat;
1032
begin
1033
  Result := FindImageFileFormatByClass(TBitmapFileFormat);
1034
end;
1035
1036
procedure TImagingBitmap.SaveToStream(Stream: TStream);
1037
begin
1038
  Imaging.PushOptions;
1039
  Imaging.SetOption(ImagingBitmapRLE, Ord(FUseRLE));
1040
  inherited SaveToStream(Stream);
1041
  Imaging.PopOptions;
1042
end;
1043
{$ENDIF}
1044
1045
{$IFDEF LINK_JPEG}
1046
1047
{ TImagingJpeg class implementation }
1048
1049
constructor TImagingJpeg.Create;
1050
begin
1051
  inherited Create;
1052
  FQuality := (GetFileFormat as TJpegFileFormat).Quality;
1053
  FProgressive := (GetFileFormat as TJpegFileFormat).Progressive;
1054
end;
1055
1056
class function TImagingJpeg.GetFileFormat: TImageFileFormat;
1057
begin
1058
  Result := FindImageFileFormatByClass(TJpegFileFormat);
1059
end;
1060
1061
{$IFDEF COMPONENT_SET_LCL}
1062
function TImagingJpeg.GetDefaultMimeType: string;
1063
begin
1064
  Result := 'image/jpeg';
1065
end;
1066
{$ENDIF}
1067
1068
procedure TImagingJpeg.SaveToStream(Stream: TStream);
1069
begin
1070
  Imaging.PushOptions;
1071
  Imaging.SetOption(ImagingJpegQuality, FQuality);
1072
  Imaging.SetOption(ImagingJpegProgressive, Ord(FProgressive));
1073
  inherited SaveToStream(Stream);
1074
  Imaging.PopOptions;
1075
end;
1076
1077
{$ENDIF}
1078
1079
{$IFDEF LINK_PNG}
1080
1081
{ TImagingPNG class implementation }
1082
1083
constructor TImagingPNG.Create;
1084
begin
1085
  inherited Create;
1086
  FPreFilter := (GetFileFormat as TPNGFileFormat).PreFilter;
1087
  FCompressLevel := (GetFileFormat as TPNGFileFormat).CompressLevel;
1088
end;
1089
1090
class function TImagingPNG.GetFileFormat: TImageFileFormat;
1091
begin
1092
  Result := FindImageFileFormatByClass(TPNGFileFormat);
1093
end;
1094
1095
procedure TImagingPNG.SaveToStream(Stream: TStream);
1096
begin
1097
  Imaging.PushOptions;
1098
  Imaging.SetOption(ImagingPNGPreFilter, FPreFilter);
1099
  Imaging.SetOption(ImagingPNGCompressLevel, FCompressLevel);
1100
  inherited SaveToStream(Stream);
1101
  Imaging.PopOptions;
1102
end;
1103
{$ENDIF}
1104
1105
{$IFDEF LINK_GIF}
1106
1107
{ TImagingGIF class implementation}
1108
1109
class function TImagingGIF.GetFileFormat: TImageFileFormat;
1110
begin
1111
  Result := FindImageFileFormatByClass(TGIFFileFormat);
1112
end;
1113
1114
{$ENDIF}
1115
1116
{$IFDEF LINK_TARGA}
1117
1118
{ TImagingTarga class implementation }
1119
1120
constructor TImagingTarga.Create;
1121
begin
1122
  inherited Create;
1123
  FUseRLE := (GetFileFormat as TTargaFileFormat).UseRLE;
1124
end;
1125
1126
class function TImagingTarga.GetFileFormat: TImageFileFormat;
1127
begin
1128
  Result := FindImageFileFormatByClass(TTargaFileFormat);
1129
end;
1130
1131
procedure TImagingTarga.SaveToStream(Stream: TStream);
1132
begin
1133
  Imaging.PushOptions;
1134
  Imaging.SetOption(ImagingTargaRLE, Ord(FUseRLE));
1135
  inherited SaveToStream(Stream);
1136
  Imaging.PopOptions;
1137
end;
1138
{$ENDIF}
1139
1140
{$IFDEF LINK_DDS}
1141
1142
{ TImagingDDS class implementation }
1143
1144
constructor TImagingDDS.Create;
1145
begin
1146
  inherited Create;
1147
  FCompression := dcNone;
1148
end;
1149
1150
class function TImagingDDS.GetFileFormat: TImageFileFormat;
1151
begin
1152
  Result := FindImageFileFormatByClass(TDDSFileFormat);
1153
end;
1154
1155
procedure TImagingDDS.SaveToStream(Stream: TStream);
1156
begin
1157
  case FCompression of
1158
    dcNone: FSavingFormat := ifUnknown;
1159
    dcDXT1: FSavingFormat := ifDXT1;
1160
    dcDXT3: FSavingFormat := ifDXT3;
1161
    dcDXT5: FSavingFormat := ifDXT5;
1162
  end;
1163
  Imaging.PushOptions;
1164
  Imaging.SetOption(ImagingDDSSaveCubeMap, Ord(False));
1165
  Imaging.SetOption(ImagingDDSSaveVolume, Ord(False));
1166
  Imaging.SetOption(ImagingDDSSaveMipMapCount, 1);
1167
  Imaging.SetOption(ImagingDDSSaveDepth, 1);
1168
  inherited SaveToStream(Stream);
1169
  Imaging.PopOptions;
1170
end;
1171
{$ENDIF}
1172
1173
{$IFDEF LINK_MNG}
1174
1175
{ TImagingMNG class implementation }
1176
1177
constructor TImagingMNG.Create;
1178
begin
1179
  inherited Create;
1180
  FLossyCompression := (GetFileFormat as TMNGFileFormat).LossyCompression;
1181
  FLossyAlpha := (GetFileFormat as TMNGFileFormat).LossyAlpha;
1182
  FPreFilter := (GetFileFormat as TMNGFileFormat).PreFilter;
1183
  FCompressLevel := (GetFileFormat as TMNGFileFormat).CompressLevel;
1184
  FQuality := (GetFileFormat as TMNGFileFormat).Quality;
1185
  FProgressive := (GetFileFormat as TMNGFileFormat).Progressive;
1186
end;
1187
1188
class function TImagingMNG.GetFileFormat: TImageFileFormat;
1189
begin
1190
  Result := FindImageFileFormatByClass(TMNGFileFormat);
1191
end;
1192
1193
{$IFDEF COMPONENT_SET_LCL}
1194
function TImagingMNG.GetDefaultMimeType: string;
1195
begin
1196
  Result := 'video/mng';
1197
end;
1198
{$ENDIF}
1199
1200
procedure TImagingMNG.SaveToStream(Stream: TStream);
1201
begin
1202
  Imaging.PushOptions;
1203
  Imaging.SetOption(ImagingMNGLossyCompression, Ord(FLossyCompression));
1204
  Imaging.SetOption(ImagingMNGLossyAlpha, Ord(FLossyAlpha));
1205
  Imaging.SetOption(ImagingMNGPreFilter, FPreFilter);
1206
  Imaging.SetOption(ImagingMNGCompressLevel, FCompressLevel);
1207
  Imaging.SetOption(ImagingMNGQuality, FQuality);
1208
  Imaging.SetOption(ImagingMNGProgressive, Ord(FProgressive));
1209
  inherited SaveToStream(Stream);
1210
  Imaging.PopOptions;
1211
end;
1212
{$ENDIF}
1213
1214
{$IFDEF LINK_JNG}
1215
1216
{ TImagingJNG class implementation }
1217
1218
constructor TImagingJNG.Create;
1219
begin
1220
  inherited Create;
1221
  FLossyAlpha := (GetFileFormat as TJNGFileFormat).LossyAlpha;
1222
  FAlphaPreFilter := (GetFileFormat as TJNGFileFormat).PreFilter;
1223
  FAlphaCompressLevel := (GetFileFormat as TJNGFileFormat).CompressLevel;
1224
  FQuality := (GetFileFormat as TJNGFileFormat).Quality;
1225
  FProgressive := (GetFileFormat as TJNGFileFormat).Progressive;
1226
end;
1227
1228
class function TImagingJNG.GetFileFormat: TImageFileFormat;
1229
begin
1230
  Result := FindImageFileFormatByClass(TJNGFileFormat);
1231
end;
1232
1233
procedure TImagingJNG.SaveToStream(Stream: TStream);
1234
begin
1235
  Imaging.PushOptions;
1236
  Imaging.SetOption(ImagingJNGLossyALpha, Ord(FLossyAlpha));
1237
  Imaging.SetOption(ImagingJNGAlphaPreFilter, FAlphaPreFilter);
1238
  Imaging.SetOption(ImagingJNGAlphaCompressLevel, FAlphaCompressLevel);
1239
  Imaging.SetOption(ImagingJNGQuality, FQuality);
1240
  Imaging.SetOption(ImagingJNGProgressive, Ord(FProgressive));
1241
  inherited SaveToStream(Stream);
1242
  Imaging.PopOptions;
1243
end;
1244
{$ENDIF}
1245
1246
initialization
1247
  RegisterTypes;
1248
finalization
1249
  UnRegisterTypes;
1250
1251
{
1252
  File Notes:
1253
1254
  -- TODOS ----------------------------------------------------
1255
    - nothing now
1256
1257
  -- 0.24.1 Changes/Bug Fixes ---------------------------------
1258
    - Fixed wrong IFDEF causing that Imaging wouldn't compile in Lazarus
1259
      with GTK2 target.
1260
    - Added commnets with code for Lazarus rev. 11861+ regarding
1261
      RawImage interface. Replace current code with that in comments
1262
      if you use Lazarus from SVN. New RawImage interface will be used by
1263
      default after next Lazarus release. 
1264
1265
  -- 0.23 Changes/Bug Fixes -----------------------------------
1266
    - Added TImagingGIF. 
1267
1268
  -- 0.21 Changes/Bug Fixes -----------------------------------
1269
    - Uses only high level interface now (except for saving options).
1270
    - Slightly changed class hierarchy. TImagingGraphic is now only for loading
1271
      and base class for savers is new TImagingGraphicForSave. Also
1272
      TImagingGraphic is now registered with all supported file formats
1273
      by TPicture's format support.
1274
1275
  -- 0.19 Changes/Bug Fixes -----------------------------------
1276
    - added DisplayImage procedures (thanks to Paul Michell, modified)
1277
    - removed RegisterTypes and UnRegisterTypes from interface section,
1278
      they are called automatically
1279
    - added procedures: ConvertImageToBitmap and ConvertBitmapToImage
1280
1281
  -- 0.17 Changes/Bug Fixes -----------------------------------
1282
    - LCL data to bitmap conversion didn?t work in Linux, fixed
1283
    - added MNG file format
1284
    - added JNG file format
1285
1286
  -- 0.15 Changes/Bug Fixes -----------------------------------
1287
    - made it LCL compatible
1288
    - made it CLX compatible
1289
    - added all initial stuff
1290
}
1291
1292
end.
1293