views:

162

answers:

4

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?

+3  A: 

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
Got 'JPEG error #53' instead. ResultStr: AnsiString; PResultStr: PAnsiChar;
Bulan
See my updated answer.
Uwe Raabe
That update did it! Thanks!(Though I should really rewrite it using something better to load/save the image)
Bulan
+1  A: 

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
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
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
+2  A: 

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

Serg
Yes, something like `(FieldByName('Picture') as TBlobField).SaveToStream(aStream)`
jasonpenny
The simple answer is, don't really know, that function is something i googled a long time ago... :)
Bulan
Rebuilt the function using TBlobfield instead and that worked too.. darn old code.. :)
Bulan
+1  A: 

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
Oops: Serg was two minutes faster...
Uwe Raabe