FormatDesc: TFormatDescriptor;
ImageData: PByte;
ImageSize: Integer;
+ CanCopy: Boolean;
+
+ procedure CopyConvert;
+ var
+ bfFormat: TbmpBitfieldFormat;
+ pSourceLine, pDestLine: PByte;
+ pSourceMD, pDestMD: Pointer;
+ x, y: Integer;
+ pixel: TglBitmapPixelData;
+ begin
+ bfFormat := TbmpBitfieldFormat.Create;
+ with aImage.DataDescription do begin
+ bfFormat.RedMask := ((1 shl RedPrec) - 1) shl RedShift;
+ bfFormat.GreenMask := ((1 shl GreenPrec) - 1) shl GreenShift;
+ bfFormat.BlueMask := ((1 shl BluePrec) - 1) shl BlueShift;
+ bfFormat.AlphaMask := ((1 shl AlphaPrec) - 1) shl AlphaShift;
+ bfFormat.PixelSize := BitsPerPixel / 8;
+ end;
+ pSourceMD := bfFormat.CreateMappingData;
+ pDestMD := FormatDesc.CreateMappingData;
+ try
+ for y := 0 to aImage.Height-1 do begin
+ pSourceLine := aImage.PixelData + y * aImage.DataDescription.BytesPerLine;
+ pDestLine := ImageData + y * Round(FormatDesc.PixelSize * aImage.Width);
+ for x := 0 to aImage.Width-1 do begin
+ bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
+ FormatDesc.Map(pixel, pDestLine, pDestMD);
+ end;
+ end;
+ finally
+ FormatDesc.FreeMappingData(pDestMD);
+ bfFormat.FreeMappingData(pSourceMD);
+ bfFormat.Free;
+ end;
+ end;
+
begin
result := false;
if not Assigned(aImage) then
if (f = tfEmpty) then
exit;
+ CanCopy :=
+ (Round(FormatDesc.PixelSize * 8) = aImage.DataDescription.Depth) and
+ (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
+
ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
ImageData := GetMem(ImageSize);
try
- Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
+ if CanCopy then
+ Move(aImage.PixelData^, ImageData^, ImageSize)
+ else
+ CopyConvert;
SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
except
if Assigned(ImageData) then