Skip to content

Commit

Permalink
Fixed #30: TIFF output compression from input
Browse files Browse the repository at this point in the history
With "-c tinput" user can now instruct program to use same TIFF compression scheme for output as was used in input file.
  • Loading branch information
galfar committed Jan 7, 2024
1 parent cf78f53 commit 8bb99df
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 28 deletions.
16 changes: 9 additions & 7 deletions Bin/RunTests.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,32 @@
@if defined param1 set DESKEW=%param1%

%DESKEW% ../TestImages/2.png || goto :error
%DESKEW% -t a -a 5 -o TestOut/Out1.tif ../TestImages/1.tif || goto :error
%DESKEW% -t a -a 10 -o TestOut/Out2.png ../TestImages/2.png || goto :error
%DESKEW% -a 10 -o TestOut/Out3.png ../TestImages/3.png || goto :error
%DESKEW% -o TestOut/Out4.png ../TestImages/4.png || goto :error
%DESKEW% -q lanczos -a 10 -o TestOut/Out5.png ../TestImages/5.png || goto :error
%DESKEW% -g c -o TestOut/OutF1550.jpg ../TestImages/F1550.jpg || goto :error
%DESKEW% -b DD -c j95,tjpeg -o TestOut/Out-tiff-jpeg.tif ../TestImages/tiff-jpeg.tif || goto :error
%DESKEW% -t 128 -o TestOut/Oute1.tif ../TestImages/1.tif || goto :error
%DESKEW% -t 128 -o TestOut/Oute2.png ../TestImages/2.png || goto :error
%DESKEW% -t 180 -o TestOut/OuteF1550.jpg ../TestImages/F1550.jpg || goto :error
%DESKEW% -b FF0000 -o TestOut/Outb1.tif ../TestImages/1.tif || goto :error
%DESKEW% -q nearest -b 00FFFF -o TestOut/Outb5.png ../TestImages/5.png || goto :error
%DESKEW% -r 214,266,933,1040 -o TestOut/Outr4.png ../TestImages/4.png || goto :error
%DESKEW% -t 100 -a 11 -b aa55cc -r 314,366,833,940 -s sp -o TestOut/Outs4.png ../TestImages/4.png || goto :error
%DESKEW% -f b1 -o TestOut/Outf1.tif ../TestImages/1.tif || goto :error
%DESKEW% -f b1 -o TestOut/Outf2.png ../TestImages/2.png || goto :error
%DESKEW% -a 5 -l 2 -o TestOut/Outl1.tif ../TestImages/1.tif || goto :error
%DESKEW% -f rgba32 -b 40ff00ff -o TestOut/Outa6.png ../TestImages/6.png || goto :error
%DESKEW% -f g8 -b 77 -s t -o TestOut/Outg6.png ../TestImages/6.png || goto :error
%DESKEW% -g d ../TestImages/5.png || goto :error

%DESKEW% -t a -a 5 -o TestOut/Out1.tif ../TestImages/1-lzw.tif || goto :error
%DESKEW% -b DD -c j95,tjpeg -o TestOut/Out-tiff-jpeg.tif ../TestImages/tiff-jpeg.tif || goto :error
%DESKEW% -t 128 -c tinput -o TestOut/Out1-g4.tif ../TestImages/1-g4.tif || goto :error
%DESKEW% -b FF0000 -c tdeflate -o TestOut/Out1-deflate.tif ../TestImages/1-lzw.tif || goto :error
%DESKEW% -f b1 -o TestOut/Out1-b1.tif ../TestImages/1-lzw.tif || goto :error
%DESKEW% -a 5 -l 2 -o TestOut/Outl1.tif ../TestImages/1-lzw.tif || goto :error

@echo:
@echo TESTS PASSED!
@echo [92mTESTS PASSED![0m
@exit /b 0

:error
@echo TESTS FAILED
@exit /b
10 changes: 5 additions & 5 deletions Bin/runtests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ done
./$DESKEW -g d ../TestImages/5.png

if [[ $NOTIFF == 0 ]]; then
./$DESKEW -t a -a 5 -o TestOut/Out1.tif ../TestImages/1.tif
./$DESKEW -t a -a 5 -o TestOut/Out1.tif ../TestImages/1-lzw.tif
./$DESKEW -b DD -c j95,tjpeg -o TestOut/Out-tiff-jpeg.tif ../TestImages/tiff-jpeg.tif
./$DESKEW -t 128 -o TestOut/Oute1.tif ../TestImages/1.tif
./$DESKEW -b FF0000 -o TestOut/Outb1.tif ../TestImages/1.tif
./$DESKEW -f b1 -o TestOut/Outf1.tif ../TestImages/1.tif
./$DESKEW -a 5 -l 2 -o TestOut/Outl1.tif ../TestImages/1.tif
./$DESKEW -t 128 -c tinput -o TestOut/Out1-g4.tif ../TestImages/1-g4.tif
./$DESKEW -b FF0000 -c tdeflate -o TestOut/Out1-deflate.tif ../TestImages/1-lzw.tif
./$DESKEW -f b1 -o TestOut/Out1-b1.tif ../TestImages/1-lzw.tif
./$DESKEW -a 5 -l 2 -o TestOut/Outl1.tif ../TestImages/1-lzw.tif
fi

echo
Expand Down
51 changes: 45 additions & 6 deletions CmdLineOptions.pas
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface
ImagingTypes,
Imaging,
ImagingUtility,
ImagingTiff,
ImageUtils;

const
Expand Down Expand Up @@ -75,13 +76,15 @@ TCmdLineOptions = class
public
constructor Create;
// Parses command line arguments to get options set by user
function ParseCommnadLine: Boolean;
function ParseCommandLine: Boolean;
function OptionsToString: string;

// Calculates final content rectangle in pixels for given image based
// on user input (content vs margin, units).
function CalcContentRectForImage(const ImageBounds: TRect; Metadata: TMetadata; out FinalRect: TRect): Boolean;

function TrySetTiffCompressionFromMetadata(Metadata: TMetadata): Boolean;

property InputFileName: string read FInputFileName;
property OutputFileName: string read FOutputFileName;
// Max expected rotation angle - algo then works in range [-MaxAngle, MaxAngle]
Expand Down Expand Up @@ -122,14 +125,17 @@ TCmdLineOptions = class
property ErrorMessage: string read FErrorMessage;
end;

const
TiffCompressionOptionAsInput = TiffCompressionOptionGroup4 + 1;

implementation

uses
TypInfo, ImagingTiff;
TypInfo;

const
TiffCompressionNames: array[TiffCompressionOptionNone..TiffCompressionOptionGroup4] of string = (
'none', 'lzw', 'rle', 'deflate', 'jpeg', 'g4'
TiffCompressionNames: array[TiffCompressionOptionNone..TiffCompressionOptionAsInput] of string = (
'none', 'lzw', 'rle', 'deflate', 'jpeg', 'g4', 'input'
);
SizeUnitTokens: array[TSizeUnit] of string = ('px', '%', 'mm', 'cm', 'in');

Expand Down Expand Up @@ -177,7 +183,7 @@ function TCmdLineOptions.GetIsValid: Boolean;
((ThresholdingMethod in [tmOtsu]) or (ThresholdingMethod = tmExplicit) and (ThresholdLevel > 0));
end;

function TCmdLineOptions.ParseCommnadLine: Boolean;
function TCmdLineOptions.ParseCommandLine: Boolean;
var
I: LongInt;
Param, Arg: string;
Expand Down Expand Up @@ -536,6 +542,39 @@ function TCmdLineOptions.CalcContentRectForImage(const ImageBounds: TRect; Metad
Result := True;
end;

function TCmdLineOptions.TrySetTiffCompressionFromMetadata(Metadata: TMetadata): Boolean;
var
CompName: string;
begin
Result := True;
Assert(FTiffCompressionScheme = TiffCompressionOptionAsInput);
if not Metadata.HasMetaItem(SMetaTiffCompressionName) then
begin
FTiffCompressionScheme := -1;
Exit(False);
end;

CompName := Metadata.MetaItems[SMetaTiffCompressionName];

// Names from "TTiffLibFileFormat.LoadData"
if CompName = 'None' then
FTiffCompressionScheme := TiffCompressionOptionNone
else if CompName = 'LZW' then
FTiffCompressionScheme := TiffCompressionOptionLzw
else if CompName = 'JPEG' then
FTiffCompressionScheme := TiffCompressionOptionJpeg
else if CompName = 'Deflate' then
FTiffCompressionScheme := TiffCompressionOptionDeflate
else if StrUtils.MatchStr(CompName, ['CCITT Group 4 Fax', 'CCITT']) then
FTiffCompressionScheme := TiffCompressionOptionGroup4;

if FTiffCompressionScheme = TiffCompressionOptionAsInput then
begin
FTiffCompressionScheme := -1;
Exit(False);
end;
end;

function TCmdLineOptions.OptionsToString: string;
var
I: Integer;
Expand Down Expand Up @@ -572,7 +611,7 @@ function TCmdLineOptions.OptionsToString: string;
end;

initialization
FloatFmtSettings := DefaultFormatSettings;
FloatFmtSettings := SysUtils.FormatSettings;
FloatFmtSettings.ThousandSeparator := #0;
FloatFmtSettings.DecimalSeparator := '.';

Expand Down
32 changes: 22 additions & 10 deletions MainUnit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ procedure WriteUsage;
WriteLn(' -c specs: Output compression specs for some file formats. Several specs');
WriteLn(' can be defined - delimited by commas. Supported specs:');
WriteLn(' jXX - JPEG compression quality, XX is in range [1,100(best)]');
WriteLn(' tSCHEME - TIFF compression scheme: none|lzw|rle|deflate|jpeg|g4');
WriteLn(' tSCHEME - TIFF compression scheme: none|lzw|rle|deflate|jpeg|g4|input');


Count := GetFileFormatCount;
Expand Down Expand Up @@ -202,13 +202,22 @@ function DoDeskew: Boolean;
Result := True;
end;

if ((Imaging.FindImageFileFormatByName(Options.OutputFileName) is TBaseTiffFileFormat) and
(Options.TiffCompressionScheme = TiffCompressionOptionGroup4)) then
// Special handling for TIFF compression
if Imaging.FindImageFileFormatByName(Options.OutputFileName) is TBaseTiffFileFormat then
begin
// Special handling for TIFF compression - user explicitly requested
// CCITT Group 4 (T.6) compression which is for 1bit images only.
OutputImage.Format := ifBinary;
Result := True;
if Options.TiffCompressionScheme = TiffCompressionOptionAsInput then
begin
if not Options.TrySetTiffCompressionFromMetadata(Imaging.GlobalMetadata) then
WriteLn('Could not set TIFF output compression from input, using default.');
end;

if Options.TiffCompressionScheme = TiffCompressionOptionGroup4 then
begin
// User explicitly requested
// CCITT Group 4 (T.6) compression which is for 1bit images only.
OutputImage.Format := ifBinary;
Result := True;
end;
end;
end;

Expand Down Expand Up @@ -322,7 +331,7 @@ procedure RunDeskew;
SrcStream.Free;
end;

procedure SetImagingOptions;
procedure SetImagingOutputOptions;
begin
if Options.JpegCompressionQuality <> -1 then
begin
Expand All @@ -331,7 +340,10 @@ procedure RunDeskew;
Imaging.SetOption(ImagingJNGQuality, Options.JpegCompressionQuality);
end;
if Options.TiffCompressionScheme <> -1 then
begin
Assert(Options.TiffCompressionScheme in [TiffCompressionOptionNone..TiffCompressionOptionGroup4]);
Imaging.SetOption(ImagingTiffCompression, Options.TiffCompressionScheme);
end;
end;

var
Expand All @@ -353,9 +365,8 @@ procedure RunDeskew;

try
try
if Options.ParseCommnadLine and Options.IsValid then
if Options.ParseCommandLine and Options.IsValid then
begin
SetImagingOptions;
if Options.ShowParams then
WriteLn(Options.OptionsToString);

Expand Down Expand Up @@ -397,6 +408,7 @@ procedure RunDeskew;
Time := GetTimeMicroseconds;
if Changed then
begin
SetImagingOutputOptions;
// Make sure recognized metadata stays (like scanning DPI info)
GlobalMetadata.CopyLoadedMetaItemsForSaving;
// Save the output
Expand Down
Binary file added TestImages/1-g4.tif
Binary file not shown.
File renamed without changes.

0 comments on commit 8bb99df

Please sign in to comment.