2
0
Johann 6 жил өмнө
parent
commit
fe076d425a

+ 8 - 3
lazpaint/dialog/ubrowseimages.pas

@@ -160,7 +160,7 @@ uses BGRAThumbnail, BGRAPaintNet, BGRAOpenRaster, BGRAReadLzp,
     Types, UResourceStrings,
     Types, UResourceStrings,
     UConfig, bgrareadjpeg, FPReadJPEG,
     UConfig, bgrareadjpeg, FPReadJPEG,
     UFileExtensions, BGRAUTF8, LazFileUtils,
     UFileExtensions, BGRAUTF8, LazFileUtils,
-    UGraph;
+    UGraph, URaw;
 
 
 var
 var
   IconCache: TStringList;
   IconCache: TStringList;
@@ -498,7 +498,8 @@ begin
   if AType = 'Folder' then AType := rsFolder else
   if AType = 'Folder' then AType := rsFolder else
   begin
   begin
     format := SuggestImageFormat(AType);
     format := SuggestImageFormat(AType);
-    if format = ifPng then AType := 'PNG' //too long to write explicitely
+    if IsRawFilename('noname'+AType) then AType := 'Raw'
+    else if format = ifPng then AType := 'PNG' //too long to write explicitely
     else if format = ifGIF then AType := 'GIF' //do not know if animated or not
     else if format = ifGIF then AType := 'GIF' //do not know if animated or not
     else if format = ifIco then AType := 'Icon'
     else if format = ifIco then AType := 'Icon'
     else if format = ifCur then AType := 'Cursor'
     else if format = ifCur then AType := 'Cursor'
@@ -541,7 +542,11 @@ var i: integer;
           try
           try
             s := FileManager.CreateFileStream(itemPath, fmOpenRead or fmShareDenyWrite);
             s := FileManager.CreateFileStream(itemPath, fmOpenRead or fmShareDenyWrite);
             try
             try
-              found := GetStreamThumbnail(s,ShellListView1.LargeIconSize,ShellListView1.LargeIconSize, BGRAPixelTransparent, True, ExtractFileExt(itemPath), FBmpIcon) <> nil;
+              if IsRawFilename(itemPath) then
+              begin
+                found := GetRawStreamThumbnail(s,ShellListView1.LargeIconSize,ShellListView1.LargeIconSize, BGRAPixelTransparent, True, FBmpIcon) <> nil;
+              end else
+                found := GetStreamThumbnail(s,ShellListView1.LargeIconSize,ShellListView1.LargeIconSize, BGRAPixelTransparent, True, ExtractFileExt(itemPath), FBmpIcon) <> nil;
             finally
             finally
               s.Free;
               s.Free;
             end;
             end;

+ 1 - 1
lazpaint/lazpaint.lpr

@@ -39,7 +39,7 @@ uses
   UMainFormLayout, USaveOption, UBrushType, ugeometricbrush,
   UMainFormLayout, USaveOption, UBrushType, ugeometricbrush,
   URainType, UFormRain, UPaletteToolbar, uselectionhighlight,
   URainType, UFormRain, UPaletteToolbar, uselectionhighlight,
   UImagePreview, UPreviewDialog, UQuestion, UTiff, UImageView,
   UImagePreview, UPreviewDialog, UQuestion, UTiff, UImageView,
-  UDarkTheme;
+  UDarkTheme, URaw;
 
 
 //sometimes LResources disappear in the uses clause
 //sometimes LResources disappear in the uses clause
 
 

+ 12 - 1
lazpaint/lazpaintmainform.pas

@@ -863,7 +863,7 @@ implementation
 uses LCLIntf, BGRAUTF8, ugraph, math, umac, uclipboard, ucursors,
 uses LCLIntf, BGRAUTF8, ugraph, math, umac, uclipboard, ucursors,
    ufilters, ULoadImage, ULoading, UFileExtensions, UBrushType,
    ufilters, ULoadImage, ULoading, UFileExtensions, UBrushType,
    ugeometricbrush, UPreviewDialog, UQuestion, BGRALayerOriginal,
    ugeometricbrush, UPreviewDialog, UQuestion, BGRALayerOriginal,
-   BGRATransform, LCVectorPolyShapes;
+   BGRATransform, LCVectorPolyShapes, URaw;
 
 
 const PenWidthFactor = 10;
 const PenWidthFactor = 10;
 
 
@@ -3588,7 +3588,12 @@ var
       StartImport;
       StartImport;
       with ComputeAcceptableImageSize(newPicture.bmp.Width,newPicture.bmp.Height) do
       with ComputeAcceptableImageSize(newPicture.bmp.Width,newPicture.bmp.Height) do
         if (cx < newPicture.bmp.Width) or (cy < newPicture.bmp.Height) then
         if (cx < newPicture.bmp.Width) or (cy < newPicture.bmp.Height) then
+        begin
+          MessagePopupForever(rsResamplingImage);
+          LazPaintInstance.UpdateWindows;
           BGRAReplace(newPicture.bmp, newPicture.bmp.Resample(cx,cy,rmFineResample));
           BGRAReplace(newPicture.bmp, newPicture.bmp.Resample(cx,cy,rmFineResample));
+          MessagePopupHide
+        end;
       image.Assign(newPicture.bmp,True, false);
       image.Assign(newPicture.bmp,True, false);
       newPicture.bmp := nil;
       newPicture.bmp := nil;
       EndImport(newPicture.bpp, newPicture.frameIndex);
       EndImport(newPicture.bpp, newPicture.frameIndex);
@@ -3628,6 +3633,12 @@ begin
       ImportNewPicture;
       ImportNewPicture;
     end
     end
     else
     else
+    if IsRawFilename(filenameUTF8) then
+    begin
+      newPicture.bmp := GetRawFileImage(filenameUTF8);
+      newPicture.bpp := 0;
+      ImportNewPicture;
+    end else
     if format in[ifIco,ifCur] then
     if format in[ifIco,ifCur] then
     begin
     begin
       newPicture := ShowPreviewDialog(LazPaintInstance, FilenameUTF8, rsIconOrCursor, ASkipDialogIfSingleImage);
       newPicture := ShowPreviewDialog(LazPaintInstance, FilenameUTF8, rsIconOrCursor, ASkipDialogIfSingleImage);

+ 2 - 1
lazpaint/ufileextensions.pas

@@ -41,7 +41,7 @@ implementation
 
 
 uses Masks, LazUTF8, UResourceStrings, BGRASVG,
 uses Masks, LazUTF8, UResourceStrings, BGRASVG,
      BGRALayerOriginal, BGRASVGOriginal, BGRAGradientOriginal,
      BGRALayerOriginal, BGRASVGOriginal, BGRAGradientOriginal,
-     LCVectorOriginal, LCVectorShapes;
+     LCVectorOriginal, LCVectorShapes, URaw;
 
 
 function GetSelectedFilterExtensions(const Filter: string;
 function GetSelectedFilterExtensions(const Filter: string;
   FilterIndex: integer; ARemoveLeadingDot: boolean): TStringList;
   FilterIndex: integer; ARemoveLeadingDot: boolean): TStringList;
@@ -321,6 +321,7 @@ initialization
   RegisterPicExt('Tiff','tif;tiff', [eoReadable,eoWritable]);
   RegisterPicExt('Tiff','tif;tiff', [eoReadable,eoWritable]);
   RegisterPicExt('X PixMap','xpm', [eoReadable,eoWritable]);
   RegisterPicExt('X PixMap','xpm', [eoReadable,eoWritable]);
   RegisterPicExt('X Window','xwd', [eoReadable]);
   RegisterPicExt('X Window','xwd', [eoReadable]);
+  RegisterPicExt('Raw',AllRawExtensions, [eoReadable]);
 
 
 end.
 end.
 
 

+ 14 - 1
lazpaint/uimagepreview.pas

@@ -100,7 +100,7 @@ type
 implementation
 implementation
 
 
 uses FPimage, BGRAReadJpeg, BGRAOpenRaster, BGRAPaintNet, BGRAReadLzp, Dialogs, UNewimage,
 uses FPimage, BGRAReadJpeg, BGRAOpenRaster, BGRAPaintNet, BGRAReadLzp, Dialogs, UNewimage,
-  LCLType, BGRAPhoxo, BGRASVG, math;
+  LCLType, BGRAPhoxo, BGRASVG, math, URaw;
 
 
 { TImagePreview }
 { TImagePreview }
 
 
@@ -844,6 +844,19 @@ begin
     try
     try
       source := FileManager.CreateFileStream(FFilename, fmOpenRead or fmShareDenyWrite);
       source := FileManager.CreateFileStream(FFilename, fmOpenRead or fmShareDenyWrite);
       FImageFormat := DetectFileFormat(source,ExtractFileExt(FFilename));
       FImageFormat := DetectFileFormat(source,ExtractFileExt(FFilename));
+      if IsRawFilename(FFilename) then
+      begin
+        try
+          FSingleImage := GetRawStreamImage(source);
+          FImageNbLayers := 1;
+        except
+          on ex: Exception do
+          begin
+            FLoadError:= ex.Message;
+            FreeAndNil(FSingleImage);
+          end;
+        end;
+      end else
       case FImageFormat of
       case FImageFormat of
       ifGif:
       ifGif:
         begin
         begin

+ 7 - 1
lazpaint/uloadimage.pas

@@ -18,7 +18,7 @@ implementation
 uses FileUtil, BGRAAnimatedGif, Graphics, UMultiImage,
 uses FileUtil, BGRAAnimatedGif, Graphics, UMultiImage,
   BGRAReadLzp, LCLProc, BGRABitmapTypes, BGRAReadPng,
   BGRAReadLzp, LCLProc, BGRABitmapTypes, BGRAReadPng,
   UFileSystem, BGRAIconCursor, BGRAReadTiff,
   UFileSystem, BGRAIconCursor, BGRAReadTiff,
-  Dialogs, math;
+  Dialogs, math, URaw;
 
 
 function LoadIcoMultiImageFromStream(AStream: TStream): ArrayOfImageEntry;
 function LoadIcoMultiImageFromStream(AStream: TStream): ArrayOfImageEntry;
 var ico: TBGRAIconCursor; i: integer;
 var ico: TBGRAIconCursor; i: integer;
@@ -120,6 +120,7 @@ function AbleToLoadUTF8(AFilename: string): boolean;
 var
 var
   s: TStream;
   s: TStream;
 begin
 begin
+  if IsRawFilename(AFilename) then exit(true);
   s := FileManager.CreateFileStream(AFilename, fmOpenRead or fmShareDenyWrite);
   s := FileManager.CreateFileStream(AFilename, fmOpenRead or fmShareDenyWrite);
   try
   try
     result := DefaultBGRAImageReader[DetectFileFormat(s, ExtractFileExt(AFilename))] <> nil;
     result := DefaultBGRAImageReader[DetectFileFormat(s, ExtractFileExt(AFilename))] <> nil;
@@ -187,6 +188,11 @@ begin
   s := FileManager.CreateFileStream(AFilename, fmOpenRead or fmShareDenyWrite);
   s := FileManager.CreateFileStream(AFilename, fmOpenRead or fmShareDenyWrite);
   try
   try
     format := DetectFileFormat(s, ExtractFileExt(AFilename));
     format := DetectFileFormat(s, ExtractFileExt(AFilename));
+    if IsRawFilename(AFilename) then
+    begin
+      result.bmp := GetRawStreamImage(s);
+      result.bpp:= 0;
+    end else
     if format in[ifIco,ifCur] then
     if format in[ifIco,ifCur] then
     begin
     begin
       multi := LoadIcoMultiImageFromStream(s);
       multi := LoadIcoMultiImageFromStream(s);

+ 216 - 0
lazpaint/uraw.pas

@@ -0,0 +1,216 @@
+unit URaw;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, FPimage, BGRABitmap, BGRABitmapTypes, Controls;
+
+type
+  TRawExtension = record
+    ext: string;
+    brand: string;
+  end;
+
+const
+  RawFileExtensions: array[0..28] of TRawExtension =
+    ((ext:'3fr'; brand:'Hasselblad'),
+     (ext:'ari'; brand:'Arri_Alexa'),
+     (ext:'arw;srf;sr2'; brand:'Sony'),
+     (ext:'bay'; brand:'Casio'),
+     (ext:'braw'; brand:'Blackmagic Design'),
+     (ext:'cri'; brand:'Cintel'),
+     (ext:'crw;cr2;cr3'; brand:'Canon'),
+     (ext:'cap;iiq;eip'; brand:'Phase_One'),
+     (ext:'dcs;dcr;drf;k25;kdc'; brand:'Kodak'),
+     (ext:'dng'; brand:'Adobe'),
+     (ext:'erf'; brand:'Epson'),
+     (ext:'fff'; brand:'Imacon/Hasselblad raw'),
+     (ext:'gpr'; brand:'GoPro'),
+     (ext:'mef'; brand:'Mamiya'),
+     (ext:'mdc'; brand:'Minolta, Agfa'),
+     (ext:'mos'; brand:'Leaf'),
+     (ext:'mrw'; brand:'Minolta, Konica Minolta'),
+     (ext:'nef;nrw'; brand:'Nikon'),
+     (ext:'orf'; brand:'Olympus'),
+     (ext:'pef;ptx'; brand:'Pentax'),
+     (ext:'pxn'; brand:'Logitech'),
+     (ext:'R3D'; brand:'RED Digital Cinema'),
+     (ext:'raf'; brand:'Fuji'),
+     (ext:'raw'; brand:'Panasonic/Leica'),
+     (ext:'rw2'; brand:'Panasonic'),
+     (ext:'rwl;dng'; brand:'Leica'),
+     (ext:'rwz'; brand:'Rawzor'),
+     (ext:'srw'; brand:'Samsung'),
+     (ext:'x3f'; brand:'Sigma'));
+
+var
+  AllRawExtensions: string;
+
+function GetRawStreamThumbnail(AStream: TStream; AWidth,AHeight: integer;
+  ABackColor: TBGRAPixel; ACheckers: boolean; ADest: TBGRABitmap= nil): TBGRABitmap;
+function GetRawStreamImage(AStream: TStream): TBGRABitmap;
+function IsRawFilename(AFilename: string): boolean;
+function GetRawFileImage(AFilename: string): TBGRABitmap;
+
+implementation
+
+uses process, BGRAThumbnail, UResourceStrings, UFileSystem, Forms;
+
+function GetAllRawExtensions: string;
+var
+  i: Integer;
+begin
+  result := '';
+  for i := low(RawFileExtensions) to high(RawFileExtensions) do
+  begin
+    if result <> '' then result += ';';
+    result += RawFileExtensions[i].ext;
+  end;
+end;
+
+procedure RunDCRaw(AOptions: array of string;
+  AInputStream, AOutputStream: TStream);
+var
+  tempName,tempOutName: String;
+  s: TFileStream;
+  p: TProcess;
+  available: DWord;
+  i: Integer;
+  consoleOut, tiffOut: boolean;
+begin
+  tempName := '';
+  p := nil;
+  try
+    tempName := GetTempFileName;
+    s := TFileStream.Create(tempName, fmCreate);
+    try
+      s.CopyFrom(AInputStream, AInputStream.Size);
+    finally
+      s.Free;
+    end;
+
+    p := TProcess.Create(nil);
+    try
+      p.Options:= p.Options+[poStderrToOutPut];
+      p.Executable:= 'dcraw';
+
+      consoleOut := false;
+      tiffOut := false;
+      for i := 0 to High(AOptions) do
+      begin
+        p.Parameters.Add(AOptions[i]);
+        if AOptions[i] = '-c' then consoleOut := true;
+        if AOptions[i] = '-T' then tiffOut := true;
+      end;
+      p.Parameters.Add(tempName);
+
+      if consoleOut then
+      begin
+        p.Options:= p.Options+[poUsePipes];
+        p.PipeBufferSize:= 524288;
+        p.Execute;
+        while p.Running do
+        begin
+          available:=P.Output.NumBytesAvailable;
+          if available > 0 then
+            AOutputStream.CopyFrom(P.Output, available)
+          else
+            sleep(30);
+        end;
+        available:=P.Output.NumBytesAvailable;
+        if available > 0 then
+          AOutputStream.CopyFrom(P.Output, available);
+      end else
+      begin
+        if tiffOut then
+          tempOutName := ChangeFileExt(tempName, '.tiff')
+        else
+          tempOutName := ChangeFileExt(tempName, '.ppm');
+        p.Execute;
+        try
+          p.WaitOnExit;
+          if not FileExists(tempOutName) then
+            raise exception.Create(rsErrorDecodingRaw);
+          s := TFileStream.Create(tempOutName, fmOpenRead);
+          try
+            AOutputStream.CopyFrom(s, s.Size);
+          finally
+            s.Free;
+          end;
+        finally
+          if FileExists(tempOutName) then DeleteFile(tempOutName);
+        end;
+      end;
+    finally
+      FreeAndNil(p);
+    end;
+  finally
+    if FileExists(tempName) then DeleteFile(tempName);
+  end;
+end;
+
+function GetRawStreamThumbnail(AStream: TStream; AWidth, AHeight: integer;
+  ABackColor: TBGRAPixel; ACheckers: boolean; ADest: TBGRABitmap): TBGRABitmap;
+var
+  thumbData: TMemoryStream;
+begin
+  result := nil;
+  thumbData := TMemoryStream.Create;
+  try
+    RunDCRaw(['-c','-e'],AStream,thumbData);
+    thumbData.Position:= 0;
+    result := GetStreamThumbnail(thumbData, AWidth,AHeight, ABackColor,ACheckers,'',ADest);
+  finally
+    thumbData.Free;
+  end;
+end;
+
+function GetRawStreamImage(AStream: TStream): TBGRABitmap;
+var
+  imageData: TMemoryStream;
+  prevCursor: TCursor;
+begin
+  prevCursor := Screen.Cursor;
+  Screen.Cursor:= crHourGlass;
+  result := nil;
+  imageData := TMemoryStream.Create;
+  try
+    RunDCRaw(['-T'],AStream,imageData);
+    imageData.Position:= 0;
+    result := TBGRABitmap.Create(imageData);
+  finally
+    imageData.Free;
+    Screen.Cursor:= prevCursor;
+  end;
+end;
+
+function IsRawFilename(AFilename: string): boolean;
+var
+  ext: String;
+begin
+  ext := LowerCase(ExtractFileExt(AFilename));
+  delete(ext,1,1);
+  result := Pos(';'+ext+';',';'+AllRawExtensions+';') <> 0;
+end;
+
+function GetRawFileImage(AFilename: string): TBGRABitmap;
+var
+  s: TStream;
+begin
+  s := FileManager.CreateFileStream(AFilename, fmOpenRead);
+  result := nil;
+  try
+    result := GetRawStreamImage(s);
+  finally
+    s.Free;
+  end;
+end;
+
+initialization
+
+  AllRawExtensions := GetAllRawExtensions;
+
+end.
+

+ 2 - 0
lazpaint/uresourcestrings.pas

@@ -30,6 +30,7 @@ resourcestring
   rsEnterLayerName='Enter layer name:';
   rsEnterLayerName='Enter layer name:';
   rsFileExtensionNotSupported='This file extension is not supported.';
   rsFileExtensionNotSupported='This file extension is not supported.';
   rsFileFormatNotRecognized='The file format has not been recognized.';
   rsFileFormatNotRecognized='The file format has not been recognized.';
+  rsErrorDecodingRaw='Error decoding raw image.';
   rsErrorLoadingOriginal='Error while loading original however layer can be rasterized.';
   rsErrorLoadingOriginal='Error while loading original however layer can be rasterized.';
   rsRasterLayer = 'Raster layer';
   rsRasterLayer = 'Raster layer';
   rsTransformedRasterLayer = 'Transformed raster layer';
   rsTransformedRasterLayer = 'Transformed raster layer';
@@ -95,6 +96,7 @@ resourcestring
 
 
   rsRepeatImage='Repeat image';
   rsRepeatImage='Repeat image';
   rsCanvasSize='Canvas size';
   rsCanvasSize='Canvas size';
+  rsResamplingImage='Resampling image...';
 
 
   rsRed='Red';
   rsRed='Red';
   rsGreen='Green';
   rsGreen='Green';