Browse Source

support for WebP images

johann 5 years ago
parent
commit
44b34ccf73
4 changed files with 258 additions and 93 deletions
  1. 123 86
      lazpaint/dialog/usaveoption.lfm
  2. 122 7
      lazpaint/dialog/usaveoption.pas
  3. 12 0
      lazpaint/uconfig.pas
  4. 1 0
      lazpaint/ufileextensions.pas

+ 123 - 86
lazpaint/dialog/usaveoption.lfm

@@ -1,132 +1,144 @@
 object FSaveOption: TFSaveOption
 object FSaveOption: TFSaveOption
   Left = 375
   Left = 375
-  Height = 491
-  Top = 181
-  Width = 596
+  Height = 777
+  Top = 62
+  Width = 944
   BorderIcons = [biSystemMenu, biMaximize]
   BorderIcons = [biSystemMenu, biMaximize]
   Caption = 'Save'
   Caption = 'Save'
-  ClientHeight = 491
-  ClientWidth = 596
+  ClientHeight = 777
+  ClientWidth = 944
+  DesignTimePPI = 152
   OnCreate = FormCreate
   OnCreate = FormCreate
   OnDestroy = FormDestroy
   OnDestroy = FormDestroy
   OnHide = FormHide
   OnHide = FormHide
   LCLVersion = '2.0.2.0'
   LCLVersion = '2.0.2.0'
   object Panel_Option: TPanel
   object Panel_Option: TPanel
     Left = 0
     Left = 0
-    Height = 491
+    Height = 777
     Top = 0
     Top = 0
-    Width = 134
+    Width = 207
     Align = alLeft
     Align = alLeft
     AutoSize = True
     AutoSize = True
     BevelOuter = bvNone
     BevelOuter = bvNone
-    ClientHeight = 491
-    ClientWidth = 134
+    ClientHeight = 777
+    ClientWidth = 207
+    ParentFont = False
     TabOrder = 0
     TabOrder = 0
     object Panel_BitsPerPixel: TPanel
     object Panel_BitsPerPixel: TPanel
       Left = 0
       Left = 0
-      Height = 187
+      Height = 237
       Top = 0
       Top = 0
-      Width = 134
+      Width = 207
       Align = alTop
       Align = alTop
       AutoSize = True
       AutoSize = True
       ChildSizing.LeftRightSpacing = 4
       ChildSizing.LeftRightSpacing = 4
       ChildSizing.TopBottomSpacing = 4
       ChildSizing.TopBottomSpacing = 4
       ChildSizing.Layout = cclLeftToRightThenTopToBottom
       ChildSizing.Layout = cclLeftToRightThenTopToBottom
       ChildSizing.ControlsPerLine = 1
       ChildSizing.ControlsPerLine = 1
-      ClientHeight = 187
-      ClientWidth = 134
+      ClientHeight = 237
+      ClientWidth = 207
+      ParentFont = False
       TabOrder = 0
       TabOrder = 0
       object Label_ColorDepth: TLabel
       object Label_ColorDepth: TLabel
         Left = 4
         Left = 4
-        Height = 17
+        Height = 25
         Top = 4
         Top = 4
-        Width = 93
+        Width = 136
         Caption = 'Color depth:'
         Caption = 'Color depth:'
         ParentColor = False
         ParentColor = False
+        ParentFont = False
       end
       end
       object RadioButton_2Colors: TRadioButton
       object RadioButton_2Colors: TRadioButton
         Left = 4
         Left = 4
-        Height = 23
-        Top = 21
-        Width = 93
+        Height = 29
+        Top = 29
+        Width = 136
         Caption = '2 colors'
         Caption = '2 colors'
         OnChange = RadioButton_BitsPerPixelChange
         OnChange = RadioButton_BitsPerPixelChange
+        ParentFont = False
         TabOrder = 0
         TabOrder = 0
       end
       end
       object RadioButton_16Colors: TRadioButton
       object RadioButton_16Colors: TRadioButton
         Left = 4
         Left = 4
-        Height = 23
-        Top = 44
-        Width = 93
+        Height = 29
+        Top = 58
+        Width = 136
         Caption = '16 colors'
         Caption = '16 colors'
         OnChange = RadioButton_BitsPerPixelChange
         OnChange = RadioButton_BitsPerPixelChange
+        ParentFont = False
         TabOrder = 1
         TabOrder = 1
       end
       end
       object RadioButton_256Colors: TRadioButton
       object RadioButton_256Colors: TRadioButton
         Left = 4
         Left = 4
-        Height = 23
-        Top = 67
-        Width = 93
+        Height = 29
+        Top = 87
+        Width = 136
         Caption = '256 colors'
         Caption = '256 colors'
         OnChange = RadioButton_BitsPerPixelChange
         OnChange = RadioButton_BitsPerPixelChange
+        ParentFont = False
         TabOrder = 3
         TabOrder = 3
       end
       end
       object RadioButton_MioMap: TRadioButton
       object RadioButton_MioMap: TRadioButton
         Left = 4
         Left = 4
-        Height = 23
-        Top = 90
-        Width = 93
+        Height = 29
+        Top = 116
+        Width = 136
         Caption = 'MioMap'
         Caption = 'MioMap'
         OnChange = RadioButton_BitsPerPixelChange
         OnChange = RadioButton_BitsPerPixelChange
+        ParentFont = False
         TabOrder = 5
         TabOrder = 5
       end
       end
       object RadioButton_24BitsPerPixel: TRadioButton
       object RadioButton_24BitsPerPixel: TRadioButton
         Left = 4
         Left = 4
-        Height = 23
-        Top = 113
-        Width = 93
+        Height = 29
+        Top = 145
+        Width = 136
         Caption = '24 bits'
         Caption = '24 bits'
         OnChange = RadioButton_BitsPerPixelChange
         OnChange = RadioButton_BitsPerPixelChange
+        ParentFont = False
         TabOrder = 2
         TabOrder = 2
       end
       end
       object RadioButton_32BitsPerPixel: TRadioButton
       object RadioButton_32BitsPerPixel: TRadioButton
         Left = 4
         Left = 4
-        Height = 23
-        Top = 136
-        Width = 93
+        Height = 29
+        Top = 174
+        Width = 136
         Caption = '32 bits'
         Caption = '32 bits'
         Checked = True
         Checked = True
         OnChange = RadioButton_BitsPerPixelChange
         OnChange = RadioButton_BitsPerPixelChange
+        ParentFont = False
         TabOrder = 6
         TabOrder = 6
         TabStop = True
         TabStop = True
       end
       end
       object CheckBox_Dithering: TCheckBox
       object CheckBox_Dithering: TCheckBox
         Left = 4
         Left = 4
-        Height = 23
-        Top = 159
-        Width = 93
+        Height = 29
+        Top = 203
+        Width = 136
         Caption = 'Dithering'
         Caption = 'Dithering'
         Checked = True
         Checked = True
         OnChange = CheckBox_DitheringChange
         OnChange = CheckBox_DitheringChange
+        ParentFont = False
         State = cbChecked
         State = cbChecked
         TabOrder = 4
         TabOrder = 4
       end
       end
     end
     end
     object Panel_Quality: TPanel
     object Panel_Quality: TPanel
       Left = 0
       Left = 0
-      Height = 206
-      Top = 187
-      Width = 134
+      Height = 326
+      Top = 237
+      Width = 207
       Align = alTop
       Align = alTop
       BorderWidth = 4
       BorderWidth = 4
-      ClientHeight = 206
-      ClientWidth = 134
+      ClientHeight = 326
+      ClientWidth = 207
+      ParentFont = False
       TabOrder = 1
       TabOrder = 1
       object TrackBar_Quality: TTrackBar
       object TrackBar_Quality: TTrackBar
         Left = 5
         Left = 5
-        Height = 150
-        Top = 51
-        Width = 100
+        Height = 217
+        Top = 71
+        Width = 158
         Frequency = 10
         Frequency = 10
         Max = 100
         Max = 100
         OnChange = TrackBar_QualityChange
         OnChange = TrackBar_QualityChange
@@ -134,142 +146,167 @@ object FSaveOption: TFSaveOption
         Position = 100
         Position = 100
         Reversed = True
         Reversed = True
         Align = alClient
         Align = alClient
+        ParentFont = False
         TabOrder = 0
         TabOrder = 0
       end
       end
       object Label1: TLabel
       object Label1: TLabel
         Left = 5
         Left = 5
-        Height = 17
+        Height = 25
         Top = 5
         Top = 5
-        Width = 124
+        Width = 197
         Align = alTop
         Align = alTop
         Caption = 'Quality:'
         Caption = 'Quality:'
         ParentColor = False
         ParentColor = False
+        ParentFont = False
       end
       end
       object Edit_QualityValue: TEdit
       object Edit_QualityValue: TEdit
         Left = 5
         Left = 5
-        Height = 29
-        Top = 22
-        Width = 124
+        Height = 37
+        Top = 30
+        Width = 197
         Align = alTop
         Align = alTop
+        BorderSpacing.Bottom = 4
         MaxLength = 4
         MaxLength = 4
         OnChange = Edit_QualityValueChange
         OnChange = Edit_QualityValueChange
         OnExit = Edit_QualityValueExit
         OnExit = Edit_QualityValueExit
+        ParentFont = False
         TabOrder = 1
         TabOrder = 1
       end
       end
       object Panel_Percent: TPanel
       object Panel_Percent: TPanel
-        Left = 105
-        Height = 150
-        Top = 51
-        Width = 24
+        Left = 163
+        Height = 217
+        Top = 71
+        Width = 39
         Align = alRight
         Align = alRight
         AutoSize = True
         AutoSize = True
         BevelOuter = bvNone
         BevelOuter = bvNone
-        ClientHeight = 150
-        ClientWidth = 24
+        ClientHeight = 217
+        ClientWidth = 39
+        ParentFont = False
         TabOrder = 2
         TabOrder = 2
         object Label_1: TLabel
         object Label_1: TLabel
           Left = 0
           Left = 0
-          Height = 17
+          Height = 25
           Top = 0
           Top = 0
-          Width = 24
+          Width = 39
           Align = alTop
           Align = alTop
           Caption = '100'
           Caption = '100'
           ParentColor = False
           ParentColor = False
+          ParentFont = False
         end
         end
         object Label_0: TLabel
         object Label_0: TLabel
           Left = 0
           Left = 0
-          Height = 17
-          Top = 133
-          Width = 24
+          Height = 25
+          Top = 192
+          Width = 39
           Align = alBottom
           Align = alBottom
           Caption = '0'
           Caption = '0'
           ParentColor = False
           ParentColor = False
+          ParentFont = False
         end
         end
         object Label_50: TLabel
         object Label_50: TLabel
           Left = 0
           Left = 0
-          Height = 116
-          Top = 17
-          Width = 24
+          Height = 167
+          Top = 25
+          Width = 39
           Align = alClient
           Align = alClient
           Caption = '50'
           Caption = '50'
           Layout = tlCenter
           Layout = tlCenter
           ParentColor = False
           ParentColor = False
+          ParentFont = False
         end
         end
       end
       end
+      object CheckBox_Lossless: TCheckBox
+        Left = 5
+        Height = 29
+        Top = 292
+        Width = 197
+        Align = alBottom
+        BorderSpacing.Top = 4
+        Caption = 'Lossless'
+        OnChange = CheckBox_LosslessChange
+        TabOrder = 3
+      end
     end
     end
     object Panel_OkCancel: TPanel
     object Panel_OkCancel: TPanel
       Left = 0
       Left = 0
-      Height = 89
-      Top = 393
-      Width = 134
+      Height = 113
+      Top = 563
+      Width = 207
       Align = alTop
       Align = alTop
       AutoSize = True
       AutoSize = True
       BorderWidth = 4
       BorderWidth = 4
-      ClientHeight = 89
-      ClientWidth = 134
+      ClientHeight = 113
+      ClientWidth = 207
+      ParentFont = False
       TabOrder = 2
       TabOrder = 2
       object Label_Size: TLabel
       object Label_Size: TLabel
         Left = 5
         Left = 5
-        Height = 17
+        Height = 25
         Top = 5
         Top = 5
-        Width = 124
+        Width = 197
         Align = alTop
         Align = alTop
         Caption = 'Size:'
         Caption = 'Size:'
         ParentColor = False
         ParentColor = False
+        ParentFont = False
       end
       end
       object Panel_Buttons: TPanel
       object Panel_Buttons: TPanel
-        Left = 71
-        Height = 62
-        Top = 22
-        Width = 58
+        Left = 116
+        Height = 78
+        Top = 30
+        Width = 86
         Align = alRight
         Align = alRight
         AutoSize = True
         AutoSize = True
         BevelOuter = bvNone
         BevelOuter = bvNone
         ChildSizing.Layout = cclLeftToRightThenTopToBottom
         ChildSizing.Layout = cclLeftToRightThenTopToBottom
         ChildSizing.ControlsPerLine = 1
         ChildSizing.ControlsPerLine = 1
-        ClientHeight = 62
-        ClientWidth = 58
+        ClientHeight = 78
+        ClientWidth = 86
+        ParentFont = False
         TabOrder = 0
         TabOrder = 0
         object Button_OK: TButton
         object Button_OK: TButton
           Left = 0
           Left = 0
-          Height = 31
+          Height = 39
           Top = 0
           Top = 0
-          Width = 58
+          Width = 86
           Caption = 'OK'
           Caption = 'OK'
           Default = True
           Default = True
           OnClick = Button_OKClick
           OnClick = Button_OKClick
+          ParentFont = False
           TabOrder = 0
           TabOrder = 0
         end
         end
         object Button_Cancel: TButton
         object Button_Cancel: TButton
           Left = 0
           Left = 0
-          Height = 31
-          Top = 31
-          Width = 58
+          Height = 39
+          Top = 39
+          Width = 86
           Cancel = True
           Cancel = True
           Caption = 'Cancel'
           Caption = 'Cancel'
           ModalResult = 2
           ModalResult = 2
+          ParentFont = False
           TabOrder = 1
           TabOrder = 1
         end
         end
       end
       end
     end
     end
   end
   end
   object BGRAPreview: TBGRAVirtualScreen
   object BGRAPreview: TBGRAVirtualScreen
-    Left = 134
-    Height = 491
+    Left = 207
+    Height = 777
     Top = 0
     Top = 0
-    Width = 462
+    Width = 737
     OnRedraw = BGRAPreviewRedraw
     OnRedraw = BGRAPreviewRedraw
     Align = alClient
     Align = alClient
     Alignment = taLeftJustify
     Alignment = taLeftJustify
     Color = clBtnFace
     Color = clBtnFace
     ParentColor = False
     ParentColor = False
+    ParentFont = False
     TabOrder = 1
     TabOrder = 1
   end
   end
   object Timer_Update: TTimer
   object Timer_Update: TTimer
     Enabled = False
     Enabled = False
     Interval = 500
     Interval = 500
     OnTimer = Timer_UpdateTimer
     OnTimer = Timer_UpdateTimer
-    left = 152
-    top = 32
+    left = 241
+    top = 51
   end
   end
 end
 end

+ 122 - 7
lazpaint/dialog/usaveoption.pas

@@ -17,6 +17,7 @@ type
     BGRAPreview: TBGRAVirtualScreen;
     BGRAPreview: TBGRAVirtualScreen;
     Button_Cancel: TButton;
     Button_Cancel: TButton;
     Button_OK: TButton;
     Button_OK: TButton;
+    CheckBox_Lossless: TCheckBox;
     CheckBox_Dithering: TCheckBox;
     CheckBox_Dithering: TCheckBox;
     Edit_QualityValue: TEdit;
     Edit_QualityValue: TEdit;
     Label1: TLabel;
     Label1: TLabel;
@@ -42,6 +43,7 @@ type
     procedure BGRAPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
     procedure BGRAPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
     procedure Button_OKClick(Sender: TObject);
     procedure Button_OKClick(Sender: TObject);
     procedure CheckBox_DitheringChange(Sender: TObject);
     procedure CheckBox_DitheringChange(Sender: TObject);
+    procedure CheckBox_LosslessChange(Sender: TObject);
     procedure Edit_QualityValueChange(Sender: TObject);
     procedure Edit_QualityValueChange(Sender: TObject);
     procedure Edit_QualityValueExit(Sender: TObject);
     procedure Edit_QualityValueExit(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormCreate(Sender: TObject);
@@ -55,24 +57,30 @@ type
     FInit: boolean;
     FInit: boolean;
     FLazPaintInstance: TLazPaintCustomInstance;
     FLazPaintInstance: TLazPaintCustomInstance;
     FOutputFilename: string;
     FOutputFilename: string;
-    FQualityVisible, FBitsPerPixelVisible: boolean;
-    FFlattenedOriginal, FJpegPreview: TBGRABitmap;
-    FBmpStream, FJpegStream, FPngStream: TMemoryStream;
+    FQualityVisible, FLosslessVisible, FBitsPerPixelVisible: boolean;
+    FFlattenedOriginal, FJpegPreview, FWebPPreview: TBGRABitmap;
+    FBmpStream, FJpegStream, FWebPStream, FPngStream: TMemoryStream;
     FFormTitle: string;
     FFormTitle: string;
     FImageFormat: TBGRAImageFormat;
     FImageFormat: TBGRAImageFormat;
     FQuantizer, FQuantizer1bit: TBGRAColorQuantizer;
     FQuantizer, FQuantizer1bit: TBGRAColorQuantizer;
     FSizeCaption: string;
     FSizeCaption: string;
     function GetBmpStreamNeeded: boolean;
     function GetBmpStreamNeeded: boolean;
     procedure BmpQualityChanged;
     procedure BmpQualityChanged;
+    function GetLosslessVisible: boolean;
     function GetPngStreamNeeded: boolean;
     function GetPngStreamNeeded: boolean;
+    function GetWebPLossless: boolean;
     procedure PngQualityChanged;
     procedure PngQualityChanged;
     function GetBitsPerPixelVisible: boolean;
     function GetBitsPerPixelVisible: boolean;
     function GetColorQuantizer: TBGRAColorQuantizer;
     function GetColorQuantizer: TBGRAColorQuantizer;
     function GetJpegPreview: TBGRABitmap;
     function GetJpegPreview: TBGRABitmap;
     procedure RequireJpegStream;
     procedure RequireJpegStream;
+    function GetWebPPreview: TBGRABitmap;
+    procedure RequireWebPStream;
     procedure MakeBmpStreamIfNeeded;
     procedure MakeBmpStreamIfNeeded;
     function GetWantedBitsPerPixel: integer;
     function GetWantedBitsPerPixel: integer;
     procedure SetJpegQuality(AValue: integer);
     procedure SetJpegQuality(AValue: integer);
+    procedure SetLosslessVisible(AValue: boolean);
+    procedure SetWebPLossless(AValue: boolean);
     procedure UpdateFileSize;
     procedure UpdateFileSize;
     procedure UpdateFileSizeTo(AValue: int64);
     procedure UpdateFileSizeTo(AValue: int64);
     function GetJpegQuality: integer;
     function GetJpegQuality: integer;
@@ -90,11 +98,13 @@ type
     function GetOriginalBitDepth: integer;
     function GetOriginalBitDepth: integer;
     procedure DoUpdateBitmap;
     procedure DoUpdateBitmap;
     procedure JpegQualityChanged;
     procedure JpegQualityChanged;
+    procedure WebPQualityChanged;
     procedure LayoutRadioButtonDepth;
     procedure LayoutRadioButtonDepth;
     procedure MakePngStreamIfNeeded;
     procedure MakePngStreamIfNeeded;
   public
   public
     { public declarations }
     { public declarations }
     property QualityVisible: boolean read GetQualityVisible write SetQualityVisible;
     property QualityVisible: boolean read GetQualityVisible write SetQualityVisible;
+    property LosslessVisible: boolean read GetLosslessVisible write SetLosslessVisible;
     property BitsPerPixelVisible: boolean read GetBitsPerPixelVisible write SetBitsPerPixelVisible;
     property BitsPerPixelVisible: boolean read GetBitsPerPixelVisible write SetBitsPerPixelVisible;
     property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
     property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
     property OutputFilename: string read FOutputFilename write SetOutputFilename;
     property OutputFilename: string read FOutputFilename write SetOutputFilename;
@@ -103,6 +113,8 @@ type
     property QuantizerNeeded: boolean read GetQuantizerNeeded;
     property QuantizerNeeded: boolean read GetQuantizerNeeded;
     property JpegPreview: TBGRABitmap read GetJpegPreview;
     property JpegPreview: TBGRABitmap read GetJpegPreview;
     property JpegQuality: integer read GetJpegQuality write SetJpegQuality;
     property JpegQuality: integer read GetJpegQuality write SetJpegQuality;
+    property WebPPreview: TBGRABitmap read GetWebPPreview;
+    property WebPLossless: boolean read GetWebPLossless write SetWebPLossless;
     property WantedBitsPerPixel: integer read GetWantedBitsPerPixel;
     property WantedBitsPerPixel: integer read GetWantedBitsPerPixel;
     property BmpStreamNeeded: boolean read GetBmpStreamNeeded;
     property BmpStreamNeeded: boolean read GetBmpStreamNeeded;
     property PngStreamNeeded: boolean read GetPngStreamNeeded;
     property PngStreamNeeded: boolean read GetPngStreamNeeded;
@@ -114,13 +126,13 @@ implementation
 
 
 uses UGraph, FPWriteJPEG, UResourceStrings, FPWriteBMP, BMPcomn,
 uses UGraph, FPWriteJPEG, UResourceStrings, FPWriteBMP, BMPcomn,
   UMySLV, BGRAWriteBmpMioMap, BGRADithering, UFileSystem, LCScaleDPI,
   UMySLV, BGRAWriteBmpMioMap, BGRADithering, UFileSystem, LCScaleDPI,
-  BGRAThumbnail, BGRAIconCursor, BGRAWinResource;
+  BGRAThumbnail, BGRAIconCursor, BGRAWinResource, BGRAWriteWebP;
 
 
 function ShowSaveOptionDialog(AInstance: TLazPaintCustomInstance; AOutputFilenameUTF8: string; ASkipOptions: boolean): boolean;
 function ShowSaveOptionDialog(AInstance: TLazPaintCustomInstance; AOutputFilenameUTF8: string; ASkipOptions: boolean): boolean;
 var f: TFSaveOption;
 var f: TFSaveOption;
 begin
 begin
   result := false;
   result := false;
-  if not ASkipOptions and (SuggestImageFormat(AOutputFilenameUTF8) in[ifBmp,ifJpeg,ifPng,ifIco,ifCur]) then
+  if not ASkipOptions and (SuggestImageFormat(AOutputFilenameUTF8) in[ifBmp,ifJpeg,ifWebP,ifPng,ifIco,ifCur]) then
   begin
   begin
     f := TFSaveOption.Create(nil);
     f := TFSaveOption.Create(nil);
     try
     try
@@ -153,6 +165,7 @@ begin
   UpdateQualityTextBox;
   UpdateQualityTextBox;
   FFormTitle:= Caption;
   FFormTitle:= Caption;
   FQualityVisible:= false;
   FQualityVisible:= false;
+  FLosslessVisible:= true;
   FBitsPerPixelVisible:= false;
   FBitsPerPixelVisible:= false;
   Panel_Quality.Visible := FQualityVisible;
   Panel_Quality.Visible := FQualityVisible;
   Panel_BitsPerPixel.Visible := FBitsPerPixelVisible;
   Panel_BitsPerPixel.Visible := FBitsPerPixelVisible;
@@ -166,8 +179,10 @@ begin
   FreeAndNil(FQuantizer);
   FreeAndNil(FQuantizer);
   FreeAndNil(FQuantizer1bit);
   FreeAndNil(FQuantizer1bit);
   FreeAndNil(FJpegPreview);
   FreeAndNil(FJpegPreview);
+  FreeAndNil(FWebPPreview);
   FreeAndNil(FBmpStream);
   FreeAndNil(FBmpStream);
   FreeAndNil(FJpegStream);
   FreeAndNil(FJpegStream);
+  FreeAndNil(FWebPStream);
   FreeAndNil(FPngStream);
   FreeAndNil(FPngStream);
 end;
 end;
 
 
@@ -271,7 +286,12 @@ begin
   if ImageFormat = ifJpeg then
   if ImageFormat = ifJpeg then
   begin
   begin
     mustFreePic:= false;
     mustFreePic:= false;
-    picture := GetJpegPreview;
+    picture := JpegPreview;
+  end else
+  if (ImageFormat = ifWebP) and not WebPLossless then
+  begin
+    mustFreePic:= false;
+    picture := WebPPreview;
   end else
   end else
   if BmpStreamNeeded and (FBmpStream = nil) then
   if BmpStreamNeeded and (FBmpStream = nil) then
   begin
   begin
@@ -293,6 +313,7 @@ begin
     picture := FFlattenedOriginal;
     picture := FFlattenedOriginal;
   end;
   end;
   MakePngStreamIfNeeded;
   MakePngStreamIfNeeded;
+  if ImageFormat = ifWebP then RequireWebPStream;
 
 
   if (Bitmap.Width = 0) or (Bitmap.Height = 0) or (picture.Width = 0) or (picture.Height = 0) then exit;
   if (Bitmap.Width = 0) or (Bitmap.Height = 0) or (picture.Width = 0) or (picture.Height = 0) then exit;
   ratioX := Bitmap.Width/picture.Width;
   ratioX := Bitmap.Width/picture.Width;
@@ -447,6 +468,22 @@ procedure TFSaveOption.Button_OKClick(Sender: TObject);
     end;
     end;
   end;
   end;
 
 
+  procedure SaveWebP;
+  var outputStream: TStream;
+  begin
+    RequireWebPStream;
+    outputStream := FileManager.CreateFileStream(FOutputFilename,fmCreate);
+    try
+      FWebPStream.Position := 0;
+      outputStream.CopyFrom(FWebPStream, FWebPStream.Size);
+      FLazPaintInstance.Config.SetDefaultJpegQuality(JpegQuality);
+      FLazPaintInstance.Config.SetDefaultWebPLossless(WebPLossless);
+      if FLazPaintInstance.Image.NbLayers = 1 then FLazPaintInstance.Image.SetSavedFlag;
+    finally
+      outputStream.Free;
+    end;
+  end;
+
 begin
 begin
   try
   try
     Case ImageFormat of
     Case ImageFormat of
@@ -454,6 +491,10 @@ begin
               SaveJpeg;
               SaveJpeg;
               ModalResult := mrOK;
               ModalResult := mrOK;
             end;
             end;
+    ifWebP: begin
+              SaveWebP;
+              ModalResult := mrOK;
+            end;
     ifBmp:
     ifBmp:
       begin
       begin
         SaveBmp;
         SaveBmp;
@@ -489,6 +530,12 @@ begin
   NeedBitmapUpdate(True);
   NeedBitmapUpdate(True);
 end;
 end;
 
 
+procedure TFSaveOption.CheckBox_LosslessChange(Sender: TObject);
+begin
+  if FInit then exit;
+  WebPQualityChanged;
+end;
+
 procedure TFSaveOption.Edit_QualityValueExit(Sender: TObject);
 procedure TFSaveOption.Edit_QualityValueExit(Sender: TObject);
 begin
 begin
   if FInit then exit;
   if FInit then exit;
@@ -519,6 +566,11 @@ begin
   FreeAndNil(FBmpStream);
   FreeAndNil(FBmpStream);
 end;
 end;
 
 
+function TFSaveOption.GetLosslessVisible: boolean;
+begin
+  result := FLosslessVisible;
+end;
+
 function TFSaveOption.GetPngStreamNeeded: boolean;
 function TFSaveOption.GetPngStreamNeeded: boolean;
 begin
 begin
   result := (ImageFormat = ifPng) or
   result := (ImageFormat = ifPng) or
@@ -527,6 +579,11 @@ begin
           ((FFlattenedOriginal.XorMask = nil) or FFlattenedOriginal.XorMask.Empty) );
           ((FFlattenedOriginal.XorMask = nil) or FFlattenedOriginal.XorMask.Empty) );
 end;
 end;
 
 
+function TFSaveOption.GetWebPLossless: boolean;
+begin
+  result := CheckBox_Lossless.Checked;
+end;
+
 procedure TFSaveOption.UpdateQualityTextBox;
 procedure TFSaveOption.UpdateQualityTextBox;
 begin
 begin
   FInit := true;
   FInit := true;
@@ -596,6 +653,33 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TFSaveOption.GetWebPPreview: TBGRABitmap;
+begin
+  RequireWebPStream;
+  if not Assigned(FWebPPreview) then
+  begin
+    FWebPPreview := TBGRABitmap.Create;
+    FWebPStream.Position := 0;
+    FWebPPreview.LoadFromStream(FWebPStream);
+  end;
+  result := FWebPPreview;
+end;
+
+procedure TFSaveOption.RequireWebPStream;
+var writer: TBGRAWriterWebP;
+begin
+  if not Assigned(FWebPStream) then
+  begin
+    FWebPStream := TMemoryStream.Create;
+    writer := TBGRAWriterWebP.Create;
+    writer.QualityPercent := JpegQuality;
+    writer.Lossless:= WebPLossless;
+    FFlattenedOriginal.SaveToStream(FWebPStream, writer);
+    writer.Free;
+    UpdateFileSize;
+  end;
+end;
+
 procedure TFSaveOption.MakeBmpStreamIfNeeded;
 procedure TFSaveOption.MakeBmpStreamIfNeeded;
 begin
 begin
   if RadioButton_MioMap.Checked then
   if RadioButton_MioMap.Checked then
@@ -636,6 +720,18 @@ begin
   FInit := oldInit;
   FInit := oldInit;
 end;
 end;
 
 
+procedure TFSaveOption.SetLosslessVisible(AValue: boolean);
+begin
+  if FLosslessVisible = AValue then exit;
+  FLosslessVisible := AValue;
+  CheckBox_Lossless.Visible := FLosslessVisible;
+end;
+
+procedure TFSaveOption.SetWebPLossless(AValue: boolean);
+begin
+  CheckBox_Lossless.Checked := AValue;
+end;
+
 procedure TFSaveOption.UpdateFileSize;
 procedure TFSaveOption.UpdateFileSize;
 var size: int64;
 var size: int64;
 begin
 begin
@@ -666,6 +762,10 @@ begin
              UpdateFileSizeTo(-1)
              UpdateFileSizeTo(-1)
           else
           else
              UpdateFileSizeTo(FJpegStream.Size);
              UpdateFileSizeTo(FJpegStream.Size);
+  ifWebP: if FWebPStream = nil then
+             UpdateFileSizeTo(-1)
+          else
+             UpdateFileSizeTo(FWebPStream.Size);
   ifPng: if FPngStream = nil then
   ifPng: if FPngStream = nil then
              UpdateFileSizeTo(-1)
              UpdateFileSizeTo(-1)
           else
           else
@@ -701,7 +801,8 @@ var origBPP: integer;
 begin
 begin
   if FImageFormat=AValue then Exit;
   if FImageFormat=AValue then Exit;
   FImageFormat:=AValue;
   FImageFormat:=AValue;
-  QualityVisible := FImageFormat = ifJpeg;
+  QualityVisible := FImageFormat in[ifJpeg, ifWebP];
+  LosslessVisible := (FImageFormat = ifWebP);
   BitsPerPixelVisible := FImageFormat in[ifPng,ifBmp,ifIco,ifCur];
   BitsPerPixelVisible := FImageFormat in[ifPng,ifBmp,ifIco,ifCur];
   if FInit then exit;
   if FInit then exit;
   FInit := true;
   FInit := true;
@@ -792,8 +893,12 @@ begin
   FLazPaintInstance:=AValue;
   FLazPaintInstance:=AValue;
   FreeAndNil(FQuantizer);
   FreeAndNil(FQuantizer);
   FreeAndNil(FQuantizer1bit);
   FreeAndNil(FQuantizer1bit);
+  FreeAndNil(FJpegStream);
   FreeAndNil(FJpegPreview);
   FreeAndNil(FJpegPreview);
+  FreeAndNil(FWebPStream);
+  FreeAndNil(FWebPPreview);
   JpegQuality := FLazPaintInstance.Config.DefaultJpegQuality;
   JpegQuality := FLazPaintInstance.Config.DefaultJpegQuality;
+  WebPLossless := FLazPaintInstance.Config.DefaultWebPLossless;
   FFlattenedOriginal := FLazPaintInstance.Image.RenderedImage;
   FFlattenedOriginal := FLazPaintInstance.Image.RenderedImage;
   UpdateFileSize;
   UpdateFileSize;
   if LazPaintInstance.Config.DefaultSaveOptionDialogMaximized then
   if LazPaintInstance.Config.DefaultSaveOptionDialogMaximized then
@@ -862,6 +967,16 @@ procedure TFSaveOption.JpegQualityChanged;
 begin
 begin
   FreeAndNil(FJpegPreview);
   FreeAndNil(FJpegPreview);
   FreeAndNil(FJpegStream);
   FreeAndNil(FJpegStream);
+  FreeAndNil(FWebPPreview);
+  FreeAndNil(FWebPStream);
+  UpdateFileSize;
+  NeedBitmapUpdate(False);
+end;
+
+procedure TFSaveOption.WebPQualityChanged;
+begin
+  FreeAndNil(FWebPPreview);
+  FreeAndNil(FWebPStream);
   UpdateFileSize;
   UpdateFileSize;
   NeedBitmapUpdate(False);
   NeedBitmapUpdate(False);
 end;
 end;

+ 12 - 0
lazpaint/uconfig.pas

@@ -61,6 +61,8 @@ type
     procedure SetBrushes(ABrushes: TStringList);
     procedure SetBrushes(ABrushes: TStringList);
     function DefaultJpegQuality: integer;
     function DefaultJpegQuality: integer;
     procedure SetDefaultJpegQuality(value: integer);
     procedure SetDefaultJpegQuality(value: integer);
+    function DefaultWebPLossless: boolean;
+    procedure SetDefaultWebPLossless(value: boolean);
     function DefaultSaveOptionDialogMaximized: boolean;
     function DefaultSaveOptionDialogMaximized: boolean;
     procedure SetDefaultSaveOptionDialogMaximized(value: boolean);
     procedure SetDefaultSaveOptionDialogMaximized(value: boolean);
 
 
@@ -1389,6 +1391,16 @@ begin
   iniOptions.WriteInteger('General','JpegQuality',value);
   iniOptions.WriteInteger('General','JpegQuality',value);
 end;
 end;
 
 
+function TLazPaintConfig.DefaultWebPLossless: boolean;
+begin
+  result := iniOptions.ReadBool('General','WebPLossless',true);
+end;
+
+procedure TLazPaintConfig.SetDefaultWebPLossless(value: boolean);
+begin
+  iniOptions.WriteBool('General','WebPLossless',value);
+end;
+
 function TLazPaintConfig.DefaultSaveOptionDialogMaximized: boolean;
 function TLazPaintConfig.DefaultSaveOptionDialogMaximized: boolean;
 begin
 begin
   result := iniOptions.ReadBool('Window','SaveOptionDialogMaximized',false);
   result := iniOptions.ReadBool('Window','SaveOptionDialogMaximized',false);

+ 1 - 0
lazpaint/ufileextensions.pas

@@ -319,6 +319,7 @@ initialization
   RegisterPicExt('Scalable Vector Graphic','svg', [eoReadable]);
   RegisterPicExt('Scalable Vector Graphic','svg', [eoReadable]);
   RegisterPicExt('Targa','tga', [eoReadable,eoWritable]);
   RegisterPicExt('Targa','tga', [eoReadable,eoWritable]);
   RegisterPicExt('Tiff','tif;tiff', [eoReadable,eoWritable]);
   RegisterPicExt('Tiff','tif;tiff', [eoReadable,eoWritable]);
+  RegisterPicExt('WebP','webp', [eoReadable,eoWritable]);
   RegisterPicExt('X PixMap','xpm', [eoReadable,eoWritable]);
   RegisterPicExt('X PixMap','xpm', [eoReadable,eoWritable]);
   RegisterPicExt('Portable Any Map', 'pbm;pgm;ppm', [eoReadable]);
   RegisterPicExt('Portable Any Map', 'pbm;pgm;ppm', [eoReadable]);
   RegisterPicExt('X Window','xwd', [eoReadable]);
   RegisterPicExt('X Window','xwd', [eoReadable]);