3

I have an old application developed in Delphi 2006 that I now needed to make some changes in.

In this app, I'm loading images from a MsSQL "image" field but when i compile with delphi 2010 I get the error : "raised exception class EJPEG with message 'JPEG error #51'."

The code that get's the image from the database:

aStream := TMemoryStream.Create;
Try
If LoadFromBlob(FieldByName('Picture'), aStream) then
begin
    Pic:=TJpegImage.Create;

    try
        Try
            Pic.LoadFromStream(aStream);
            Picture.Assign(Pic); // <------ JPEG Error #51 here w D2010
        Except
            //something went wrong loading
            HandleImageError();    
        End;

    finally
     Pic.Free;
    end;

end;
Finally
    aStream.Free;
End;

// ............

function LoadFromBlob(const AField: TField; const Stream: TStream): boolean;
var
    ResultStr: string;
    PResultStr: PChar;
begin
    Result := false;
    if (Assigned(AField)) and (Assigned(Stream)) then begin
        try
            ResultStr := AField.Value;
            If ResultStr <> '' then
            begin
                PResultStr := PChar(ResultStr);
                Stream.Write(PResultStr^, Length(ResultStr));
                Stream.Seek(0,0);
                Result := true;
            end;
        except
        end;
    end;
end;

Googled around a bit and found out that error #51 means: JERR_NO_QUANT_TABLE, whatever that means.

When I compile with Delphi 2006, the same code works fine with no errors, so what's going wrong with D2010?

Bulan
  • 673
  • 1
  • 9
  • 24

4 Answers4

4

In D2010 Char changed from Ansi to Unicode, which means it occupies two bytes instead of one. Change your variables in LoadFromBlob to AnsiString and PAnsiChar and it should work.

Update: Instead of Field.Value (Variant) you should better access Field.AsAnsiString; The variant access might include an implicit Unicode->Ansi conversion which introduces the error.

Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130
  • Got 'JPEG error #53' instead. ResultStr: AnsiString; PResultStr: PAnsiChar; – Bulan Sep 01 '10 at 13:51
  • 1
    That update did it! Thanks! (Though I should really rewrite it using something better to load/save the image) – Bulan Sep 01 '10 at 14:35
3

You are using a rather awkward way to save a blob field to a stream. Why are you not using TBlobField.SaveToStream ?

kludg
  • 27,213
  • 5
  • 67
  • 118
1

Save your aStream out to a file and examine with a hex editor. Compare the D2006 and D2010 results. What you find there should convince you that it's nothing to do with the JPEG header, and it's likely a Unicode/Widechar issue.

Chris Thornton
  • 15,620
  • 5
  • 37
  • 62
  • I'm already conviced it has to be something with Unicode/Widechar issue, because as stated earlier, it works in D2006 with the same database. Tried to change to ansiString buth got jpeg error #53 instead – Bulan Sep 01 '10 at 14:14
  • My point is, look at the stream itself, and take JPEG out of the equation. I always like to cut big, complex problems down into small, simple ones. This is how you do that. – Chris Thornton Sep 01 '10 at 15:30
1

Why going the way over the strings anyway? What about directly writing to the stream? The image field probably is a TBlobField or TGraphicField. Those have a SaveToStream method that would perfectly suit your needs.

Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130