|
|
@@ -4968,6 +4968,42 @@ var |
|
|
|
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 |
|
|
@@ -4986,10 +5022,17 @@ begin |
|
|
|
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 |
|
|
|