I have an abstract iterator class:
TImageIterator = class (TObject)
protected
fCurLine, fCurPos: Integer;
public
function ReadNextPixel: Cardinal; virtual; abstract;
function ReadNextAsGrayscale: Cardinal; virtual; abstract;
function ReadNextSubpixel: Cardinal; virtual; abstract;
end;
and many descendants, say, T1BitImageIterator, T4BitImageIterator, T8BitImageIterator, T24BitRGBImageIterator. The point is to create an iterator (over a non-rectangular area) suitable for the current image / pixel format, and then process the image regardless of its type.
ReadNextPixel returns "raw pixel data": 0 or 1 in a 1-bit image, 0..255 in an 8-bit image, or some kind of TColor in 24-bit RGB.
ReadNextAsGrayscalereturns the brightness of a pixel in the range 0..255, which in the case of an 8-bit image will be the same as ReadNextPixel.
ReadNextSubpixel , ReadNextPixel /, R, ( ) G, B 24- RGB-.
:
function T8BitImageIterator.ReadNextPixel: Cardinal;
begin
Result:=fByteLine[fCurPos];
inch(fCurPos);
if fCurPos=fRight then begin
//going to next scanline, checking for end of iterated area etc
end;
end;
//another 'unique' functions
//code we'd be happy to get rid of
function T8BitImageIterator.ReadNextAsGrayscale: Cardinal;
begin
Result:=ReadNextPixel;
end;
function T1BitImageIterator.ReadNextSubpixel: Cardinal;
begin
Result:=ReadNextPixel;
end;
function T4BitImageIterator.ReadNextSubpixel: Cardinal;
begin
Result:=ReadNextPixel;
end;
function T8BitImageIterator.ReadNextSubpixel: Cardinal;
begin
Result:=ReadNextPixel;
end;
, , !
, :
T8BitImageIterator = class (TImageIterator)
public
function ReadNextPixel: Cardinal; override;
function ReadNextAsGrayscale=ReadNextPixel; override;
...
end;
, , .
, , . ,
TReadNextPixelProc = function: Cardinal of object;
TImageIterator = class(TObject)
...
public
ReadNextAsGrayscale: TReadNextPixelProc;
...
end;
, ( , TReadNextPixelProc ..).
:
function T8BitImageIterator.ReadNextAsGrayscale: Cardinal;
asm
jmp ReadNextPixel;
end;
ReadNextPixel ReadNextAsGrayscale, , ReadNextPixel..
: , VMT , , " " . ?