Пытаясь перевести этот метод из примеров из MS, я столкнулся с некоторыми вопросами.
Исходный код C ++ выглядит так:
void TransformImage_RGB24(
BYTE* pDest,
LONG lDestStride,
const BYTE* pSrc,
LONG lSrcStride,
DWORD dwWidthInPixels,
DWORD dwHeightInPixels
)
{
for (DWORD y = 0; y < dwHeightInPixels; y++)
{
RGBTRIPLE *pSrcPel = (RGBTRIPLE*)pSrc;
DWORD *pDestPel = (DWORD*)pDest;
for (DWORD x = 0; x < dwWidthInPixels; x++)
{
pDestPel[x] = D3DCOLOR_XRGB(
pSrcPel[x].rgbtRed,
pSrcPel[x].rgbtGreen,
pSrcPel[x].rgbtBlue
);
}
pSrc += lSrcStride;
pDest += lDestStride;
}
}
Теперь мой непосредственный перевод это:
procedure TransformImage_RGB24(pDest: Byte;
lDestStride: LONG;
pSrc: Byte;
lSrcStride: LONG;
dwWidthInPixels: DWORD;
dwHeightInPixels: DWORD);
var
x, y: Integer;
pSrcPel: RGBTRIPLE;
pDestPel: DWORD;
begin
for x:= 0 to imgTfFn.dwHeightInPixels -1 do
begin
pSrcPel:= RGBTRIPLE(imgTfFn.pSrc);
pDestPel:= DWORD(imgTfFn.pDest);
for y:= 0 to imgTfFn.dwWidthInPixels -1 do
begin
pDestPel[y]:= D3DCOLOR_XRGB(pSrcPel[y].rgbtRed,
pSrcPel[y].rgbtGreen,
pSrcPel[y].rgbtBlue);
end;
imgTfFn.pSrc:= imgTfFn.pSrc + imgTfFn.lSrcStride;
imgTfFn.pDest:= imgTfFn.pDest + imgTfFn.lDestStride;
end;
end;
Как видите, здесь есть странная проблема:
pSrcPel
объявляется и получает значение, но к чему оно будет возвращено?
То же самое с pDestPel
,
Когда я читаю этот код, для меня это абсолютное отсутствие. Например: pSrcPel
объявлен как RGBTRIPLE
, но получает входные данные от байта (pSrc
) .. да ???
Может кто-нибудь объяснить, что мне не хватает?
Источником вашей путаницы является то, что ваш перевод с самого начала был неправильным, так как вы неправильно переводите указатели.
В C ++ *
обозначает указатель. Так, BYTE*
это «указатель на BYTE
«, который PByte
(^Byte
в Дельфи. RGBTRIPLE*
это «указатель на RGBTRIPLE
«так будет PRGBTRIPLE
(^PRGBTRIPLE
в Дельфи. А также DWORD*
это «указатель на DWORD
«так будет PDWORD
(^DWORD
в Дельфи.
Кроме того, код C ++ использует арифметику указателей для доступа к массивам, на которые указывает pSrcPel
а также pDestPel
,
Попробуйте что-то более похожее на это:
{$POINTERMATH ON}
procedure TransformImage_RGB24(
pDest: PByte;
lDestStride: LONG;
pSrc: PByte;
lSrcStride: LONG;
dwWidthInPixels: DWORD;
dwHeightInPixels: DWORD)
var
x, y: DWORD;
pSrcPel: PRGBTRIPLE;
pDestPel: PDWORD;
begin
for y := 0 to dwHeightInPixels-1 do
begin
pSrcPel := PRGBTRIPLE(pSrc);
pDestPel := PDWORD(pDest);
for x := 0 to dwWidthInPixels-1 do
begin
pDestPel[x] := D3DCOLOR_XRGB(
pSrcPel[x].rgbtRed,
pSrcPel[x].rgbtGreen,
pSrcPel[x].rgbtBlue
);
end;
Inc(pSrc, lSrcStride);
Inc(pDest, lDestStride);
end;
end;
Или, если вы используете версию Delphi, которая не поддерживает {$POINTERMATH}
:
procedure TransformImage_RGB24(
pDest: PByte;
lDestStride: LONG;
pSrc: PByte;
lSrcStride: LONG;
dwWidthInPixels: DWORD;
dwHeightInPixels: DWORD)
var
x, y: DWORD;
pSrcPel: PRGBTRIPLE;
pDestPel: PDWORD;
begin
for y := 0 to dwHeightInPixels-1 do
begin
pSrcPel := PRGBTRIPLE(pSrc);
pDestPel := PDWORD(pDest);
for x := 0 to dwWidthInPixels-1 do
begin
pDestPel^ := D3DCOLOR_XRGB(
pSrcPel^.rgbtRed,
pSrcPel^.rgbtGreen,
pSrcPel^.rgbtBlue
);
Inc(pSrcPel);
Inc(pDestPel);
end;
Inc(pSrc, lSrcStride);
Inc(pDest, lDestStride);
end;
end;
Других решений пока нет …