mORMot and Open Source friends
Check-in [6dc3bbc645]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:fixed an issue when handling bitmap palette
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6dc3bbc645888be6122e38845fa8063fccf674e9
User & Date: G018869 2012-04-04 11:43:44
Context
2012-04-04
13:59
documentation enhancement about filtering and validating records check-in: 6d31a4de6f user: G018869 tags: trunk
11:43
fixed an issue when handling bitmap palette check-in: 6dc3bbc645 user: G018869 tags: trunk
05:36
compilation fix for Delphi 2009+ check-in: c3a0bfe771 user: G018869 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SynPdf.pas.

162
163
164
165
166
167
168

169
170
171
172
173
174
175
....
5018
5019
5020
5021
5022
5023
5024

5025
5026
5027
5028
5029
5030
5031
....
5041
5042
5043
5044
5045
5046
5047


5048
5049


5050
5051
5052
5053
5054
5055
5056
....
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
    made the TMetaFile rendering stronger to badly formated EMF input
  - fixed issue in TPdfDocument.CreateOrGetImage about guessing if a bitmap is
    to be reused as a pdf object
  - added TPdfDocument.ForceNoBitmapReuse property
  - added a "Decimals: cardinal=6" parameter to TPdfCanvas.ConcatToCTM
  - TPdfCanvas.SetDash parameter is now an array of integer
  - set PDF_MAX_FONTSIZE limit to 2000 - should be big enough in practice

  - fixed an issue when the first time a font was used is as Unicode
  - fixed a potential GPF issue in function HashOf() in PUREPASCAL mode (used
    to reuse any existing bitmap content within the PDF document)

}


................................................................................
{$endif}

function TPdfDocument.CreateOrGetImage(B: TBitmap; DrawAt: PPdfBox): PDFString;
var J: TJpegImage;
    Img: TPdfImage;
    Hash: TPdfImageHash;
    y,w,h,row: integer;

    Pals: array of TPaletteEntry;
const PERROW: array[TPixelFormat] of byte = (0,1,4,8,15,16,24,32,0);
procedure DoHash(bits: pointer; size: Integer);
begin // "4 algorithms to rule them all"
  Hash[0] := Hash[0] xor Hash32(bits,size);
  Hash[1] := Hash[1] xor HashOf(bits,size);
  Hash[2] := crc32(Hash[2],bits,size);
................................................................................
    row := PERROW[B.PixelFormat];
    if row=0 then begin
      B.PixelFormat := pf24bit;
      row := 24;
    end;
    fillchar(Hash,sizeof(Hash),row);
    if B.Palette<>0 then begin


      SetLength(Pals,256);
      DoHash(pointer(Pals),GetPaletteEntries(B.Palette,0,256,Pals)*sizeof(TPaletteEntry));


    end;
    row := BytesPerScanline(w,row,32);
    for y := 0 to h-1 do
      DoHash(B.ScanLine[y],row);
    result := GetXObjectImageName(Hash,w,h);
  end;
  if result='' then begin
................................................................................
      B := TBitmap(aImage) else
      NeedBitmap(pf24bit);
    try
      case B.PixelFormat of
        pf1bit, pf4bit, pf8bit: begin
          if B.PixelFormat<>pf8bit then
            NeedBitmap(pf8bit);
          SetLength(Pals,255);
          if GetPaletteEntries(B.Palette,0,256,pointer(Pals)^)=0 then
            raise EPdfInvalidValue.Create('TPdfImage');
          SetLength(Pal,7*256+2);
          WritePal(pointer(Pal),pointer(Pals));
          CA := TPdfArray.Create(nil);
          CA.AddItem(TPdfName.Create('Indexed'));
          CA.AddItem(TPdfName.Create('DeviceRGB'));
          CA.AddItem(TPdfNumber.Create(255));






>







 







>







 







>
>
|
|
>
>







 







|
|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
....
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
....
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
....
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
    made the TMetaFile rendering stronger to badly formated EMF input
  - fixed issue in TPdfDocument.CreateOrGetImage about guessing if a bitmap is
    to be reused as a pdf object
  - added TPdfDocument.ForceNoBitmapReuse property
  - added a "Decimals: cardinal=6" parameter to TPdfCanvas.ConcatToCTM
  - TPdfCanvas.SetDash parameter is now an array of integer
  - set PDF_MAX_FONTSIZE limit to 2000 - should be big enough in practice
  - fixed an issue when handling bitmap palette
  - fixed an issue when the first time a font was used is as Unicode
  - fixed a potential GPF issue in function HashOf() in PUREPASCAL mode (used
    to reuse any existing bitmap content within the PDF document)

}


................................................................................
{$endif}

function TPdfDocument.CreateOrGetImage(B: TBitmap; DrawAt: PPdfBox): PDFString;
var J: TJpegImage;
    Img: TPdfImage;
    Hash: TPdfImageHash;
    y,w,h,row: integer;
    nPals: cardinal;
    Pals: array of TPaletteEntry;
const PERROW: array[TPixelFormat] of byte = (0,1,4,8,15,16,24,32,0);
procedure DoHash(bits: pointer; size: Integer);
begin // "4 algorithms to rule them all"
  Hash[0] := Hash[0] xor Hash32(bits,size);
  Hash[1] := Hash[1] xor HashOf(bits,size);
  Hash[2] := crc32(Hash[2],bits,size);
................................................................................
    row := PERROW[B.PixelFormat];
    if row=0 then begin
      B.PixelFormat := pf24bit;
      row := 24;
    end;
    fillchar(Hash,sizeof(Hash),row);
    if B.Palette<>0 then begin
      nPals := 0;
      if (GetObject(B.Palette,sizeof(nPals),@nPals)<>0) and (nPals>0) then begin
        SetLength(Pals,nPals);
        if GetPaletteEntries(B.Palette,0,nPals,Pals)=nPals then
          DoHash(pointer(Pals),nPals*sizeof(TPaletteEntry));
      end;
    end;
    row := BytesPerScanline(w,row,32);
    for y := 0 to h-1 do
      DoHash(B.ScanLine[y],row);
    result := GetXObjectImageName(Hash,w,h);
  end;
  if result='' then begin
................................................................................
      B := TBitmap(aImage) else
      NeedBitmap(pf24bit);
    try
      case B.PixelFormat of
        pf1bit, pf4bit, pf8bit: begin
          if B.PixelFormat<>pf8bit then
            NeedBitmap(pf8bit);
          SetLength(Pals,256);
          if GetPaletteEntries(B.Palette,0,256,Pals)<>256 then
            raise EPdfInvalidValue.Create('TPdfImage');
          SetLength(Pal,7*256+2);
          WritePal(pointer(Pal),pointer(Pals));
          CA := TPdfArray.Create(nil);
          CA.AddItem(TPdfName.Create('Indexed'));
          CA.AddItem(TPdfName.Create('DeviceRGB'));
          CA.AddItem(TPdfNumber.Create(255));