You've already forked lazarus-ccr
fpexif: Add boolean property WriteJFIFandEXIF which forces writing JFIF and EXIF segments if both exist. (https://forum.lazarus.freepascal.org/index.php/topic,49648.0.html).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7427 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -57,8 +57,9 @@ type
|
|||||||
FImgHeight: Integer;
|
FImgHeight: Integer;
|
||||||
FWarnings: TStrings;
|
FWarnings: TStrings;
|
||||||
FMetadataKinds: TMetadataKinds;
|
FMetadataKinds: TMetadataKinds;
|
||||||
FHeaderSegment: TBytes;
|
FJFIFSegment: TBytes;
|
||||||
FJFXXThumbnail: TBytes;
|
FJFXXThumbnail: TBytes;
|
||||||
|
FWriteJFIFandEXIF: Boolean;
|
||||||
FComment: String;
|
FComment: String;
|
||||||
private
|
private
|
||||||
FExifData: TExifData;
|
FExifData: TExifData;
|
||||||
@ -110,6 +111,8 @@ type
|
|||||||
property MetadataKinds: TMetadataKinds read FMetadataKinds write FMetadataKinds default mdkAll;
|
property MetadataKinds: TMetadataKinds read FMetadataKinds write FMetadataKinds default mdkAll;
|
||||||
{ Warning message - NOTE: Reading of warnings is erasing the warnings list! }
|
{ Warning message - NOTE: Reading of warnings is erasing the warnings list! }
|
||||||
property Warnings: String read GetWarnings;
|
property Warnings: String read GetWarnings;
|
||||||
|
{ Write both JFIF and EXIF data if available. Normally they are mutually exclusive. }
|
||||||
|
property WriteJFIFandEXIF: Boolean read FWriteJFIFandEXIF write FWriteJFIFandEXIF;
|
||||||
|
|
||||||
property ExifData: TExifData read FExifData;
|
property ExifData: TExifData read FExifData;
|
||||||
property IptcData: TIptcData read FIptcData; // to do: rename to IptcData
|
property IptcData: TIptcData read FIptcData; // to do: rename to IptcData
|
||||||
@ -394,16 +397,21 @@ type
|
|||||||
Marker: byte;
|
Marker: byte;
|
||||||
Size: Word;
|
Size: Word;
|
||||||
end;
|
end;
|
||||||
|
const
|
||||||
|
SOI_MARKER: array[0..1] of byte = ($FF, $D8);
|
||||||
var
|
var
|
||||||
header: TSegmentHeader;
|
header: TSegmentHeader;
|
||||||
n, count: Int64;
|
n, count: Int64;
|
||||||
savedPos: Int64;
|
savedPos: Int64;
|
||||||
|
jfif: TJpegJFIFSegment;
|
||||||
begin
|
begin
|
||||||
// Write the header segment and all metadata segments stored in TImgInfo
|
// Write the header segment and all metadata segments stored in TImgInfo
|
||||||
// to the beginning of the stream
|
// to the beginning of the stream
|
||||||
AOutputStream.Position := 0;
|
AOutputStream.Position := 0;
|
||||||
WriteJpeg(AOutputStream);
|
WriteJpeg(AOutputStream);
|
||||||
|
|
||||||
|
AInputStream.Position := 0;
|
||||||
|
|
||||||
// Now write copy all other segments.
|
// Now write copy all other segments.
|
||||||
AInputStream.Position := 0;
|
AInputStream.Position := 0;
|
||||||
while AInputStream.Position < AInputStream.Size do begin
|
while AInputStream.Position < AInputStream.Size do begin
|
||||||
@ -539,8 +547,8 @@ begin
|
|||||||
if CompareMem(@Identifier[0], @sJFIF[1], Length(sJFIF)) then
|
if CompareMem(@Identifier[0], @sJFIF[1], Length(sJFIF)) then
|
||||||
begin
|
begin
|
||||||
// JFIF APP0 marker segment
|
// JFIF APP0 marker segment
|
||||||
SetLength(FHeaderSegment, size);
|
SetLength(FJFIFSegment, size);
|
||||||
Move(hdr[0], FHeaderSegment[0], size);
|
Move(hdr[0], FJFIFSegment[0], size);
|
||||||
if (JFIFVersion[0] <> 1) then
|
if (JFIFVersion[0] <> 1) then
|
||||||
exit;
|
exit;
|
||||||
end else
|
end else
|
||||||
@ -680,7 +688,7 @@ const
|
|||||||
SOI_MARKER: array[0..1] of byte = ($FF, $D8);
|
SOI_MARKER: array[0..1] of byte = ($FF, $D8);
|
||||||
COM_MARKER: array[0..1] of byte = ($FF, $FE);
|
COM_MARKER: array[0..1] of byte = ($FF, $FE);
|
||||||
JFIF_MARKER: array[0..1] of byte = ($FF, $E0);
|
JFIF_MARKER: array[0..1] of byte = ($FF, $E0);
|
||||||
JFIF: ansistring = 'JFIF'#0;
|
JFIF_ID: ansistring = 'JFIF'#0;
|
||||||
var
|
var
|
||||||
jfifSegment: TJpegJFIFSegment;
|
jfifSegment: TJpegJFIFSegment;
|
||||||
writer: TBasicMetadataWriter;
|
writer: TBasicMetadataWriter;
|
||||||
@ -691,29 +699,37 @@ begin
|
|||||||
// Write Start-of-image segment (SOI)
|
// Write Start-of-image segment (SOI)
|
||||||
AStream.WriteBuffer(SOI_MARKER, SizeOf(SOI_MARKER));
|
AStream.WriteBuffer(SOI_MARKER, SizeOf(SOI_MARKER));
|
||||||
|
|
||||||
// No Exif --> write an APP0 segment
|
// No EXIF or JFIF requested: write APP0 segment
|
||||||
if not HasExif or (FMetadataKinds * [mdkExif, mdkExifNoMakerNotes] = []) then begin
|
if (not HasExif) or
|
||||||
if Length(FHeaderSegment) = 0 then begin
|
(FMetaDataKinds * [mdkExif, mdkExifNoMakerNotes] = []) or
|
||||||
Move(JFIF[1], {%H-}JFIFSegment.Identifier[0], Length(JFIF));
|
FWriteJFIFandEXIF then
|
||||||
JFIFSegment.JFIFVersion[0] := 1;
|
begin
|
||||||
JFIFSegment.JFIFVersion[1] := 2;
|
// No Exif, no JFIF --> write a default APP0 segment
|
||||||
JFIFSegment.DensityUnit := 1; // inch
|
if Length(FJFIFSegment) = 0 then
|
||||||
JFIFSegment.XDensity := NtoBE(72); // 72 ppi
|
begin
|
||||||
JFIFSegment.YDensity := NtoBE(72);
|
Move(JFIF_ID[1], {%H-}jfifSegment.Identifier[0], Length(JFIF_ID));
|
||||||
JFIFSegment.ThumbnailWidth := 0; // no thumbnail in APP0 segment
|
jfifSegment.JFIFVersion[0] := 1;
|
||||||
JFIFSegment.ThumbnailHeight := 0;
|
jfifSegment.JFIFVersion[1] := 2;
|
||||||
AStream.WriteBuffer(JFIF_MARKER, SizeOf(JFIF_MARKER));
|
jfifSegment.DensityUnit := 1; // inch
|
||||||
WriteWord(AStream, NtoBE(Word(SizeOf(JFIFSegment) + 2)));
|
jfifSegment.XDensity := NtoBE(72); // 72 ppi
|
||||||
AStream.WriteBuffer(JFIFSegment, SizeOf(JFIFSegment));
|
jfifSegment.YDensity := NtoBE(72);
|
||||||
end else
|
jfifSegment.ThumbnailWidth := 0; // no thumbnail in APP0 segment
|
||||||
begin
|
jfifSegment.ThumbnailHeight := 0;
|
||||||
AStream.WriteBuffer(JFIF_MARKER, SizeOf(JFIF_MARKER));
|
AStream.WriteBuffer(JFIF_MARKER, SizeOf(JFIF_MARKER));
|
||||||
WriteWord(AStream, NtoBE(Word(Length(FHeaderSegment) + 2)));
|
WriteWord(AStream, NtoBE(Word(SizeOf(jfifSegment) + 2)));
|
||||||
AStream.WriteBuffer(FHeaderSegment[0], Length(FHeaderSegment));
|
AStream.WriteBuffer(jfifSegment, SizeOf(jfifSegment));
|
||||||
end;
|
end
|
||||||
end else
|
// No Exif, but JFIF --> write the JFIF segment of the file
|
||||||
|
else begin
|
||||||
|
AStream.WriteBuffer(JFIF_MARKER, SizeOf(JFIF_MARKER));
|
||||||
|
WriteWord(AStream, NToBE(Word(LengtH(FJFIFSegment) + 2)));
|
||||||
|
AStream.WriteBuffer(FJFIFSegment[0], Length(FJFIFSegment));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Exif --> Write APP1 segment
|
||||||
|
if HasExif then
|
||||||
begin
|
begin
|
||||||
// Exif --> Write APP1 segment
|
|
||||||
writer := TExifWriter.Create(Self);
|
writer := TExifWriter.Create(Self);
|
||||||
try
|
try
|
||||||
TExifWriter(writer).BigEndian:= FExifData.BigEndian;
|
TExifWriter(writer).BigEndian:= FExifData.BigEndian;
|
||||||
|
Reference in New Issue
Block a user