📄 rdtarga.pas
字号:
begin
source := tga_source_ptr (sinfo);
ptr := JSAMPLE_PTR(source^.pub.buffer^[0]);
for col := pred(cinfo^.image_width) downto 0 do
begin
source^.read_pixel (source); { Load next pixel into tga_pixel }
ptr^ := JSAMPLE (UCH(source^.tga_pixel[2])); { change BGR to RGB order }
Inc(ptr);
ptr^ := JSAMPLE (UCH(source^.tga_pixel[1]));
Inc(ptr);
ptr^ := JSAMPLE (UCH(source^.tga_pixel[0]));
Inc(ptr);
end;
get_24bit_row := 1;
end;
{ Targa also defines a 32-bit pixel format with order B,G,R,A.
We presently ignore the attribute byte, so the code for reading
these pixels is identical to the 24-bit routine above.
This works because the actual pixel length is only known to read_pixel. }
const
get_32bit_row : function (cinfo : j_compress_ptr;
sinfo : cjpeg_source_ptr) : JDIMENSION
= get_24bit_row;
{ This method is for re-reading the input data in standard top-down
row order. The entire image has already been read into whole_image
with proper conversion of pixel format, but it's in a funny row order. }
{METHODDEF}
function get_memory_row (cinfo : j_compress_ptr;
sinfo : cjpeg_source_ptr) : JDIMENSION; far;
var
source : tga_source_ptr;
source_row : JDIMENSION;
begin
source := tga_source_ptr (sinfo);
{ Compute row of source that maps to current_row of normal order }
{ For now, assume image is bottom-up and not interlaced. }
{ NEEDS WORK to support interlaced images! }
source_row := cinfo^.image_height - source^.current_row - 1;
{ Fetch that row from virtual array }
source^.pub.buffer := cinfo^.mem^.access_virt_sarray
(j_common_ptr (cinfo), source^.whole_image,
source_row, JDIMENSION (1), FALSE);
Inc(source^.current_row);
get_memory_row := 1;
end;
{ This method loads the image into whole_image during the first call on
get_pixel_rows. The get_pixel_rows pointer is then adjusted to call
get_memory_row on subsequent calls. }
{METHODDEF}
function preload_image (cinfo : j_compress_ptr;
sinfo : cjpeg_source_ptr) : JDIMENSION; far;
var
source : tga_source_ptr;
row : JDIMENSION;
progress : cd_progress_ptr;
begin
source := tga_source_ptr (sinfo);
progress := cd_progress_ptr (cinfo^.progress);
{ Read the data into a virtual array in input-file row order. }
for row := 0 to pred(cinfo^.image_height) do
begin
if (progress <> NIL) then
begin
progress^.pub.pass_counter := long (row);
progress^.pub.pass_limit := long (cinfo^.image_height);
progress^.pub.progress_monitor (j_common_ptr (cinfo));
end;
source^.pub.buffer := cinfo^.mem^.access_virt_sarray
(j_common_ptr(cinfo), source^.whole_image, row, JDIMENSION(1), TRUE);
source^.get_pixel_rows (cinfo, sinfo);
end;
if (progress <> NIL) then
Inc(progress^.completed_extra_passes);
{ Set up to read from the virtual array in unscrambled order }
source^.pub.get_pixel_rows := get_memory_row;
source^.current_row := 0;
{ And read the first row }
preload_image := get_memory_row(cinfo, sinfo);
end;
{ Read the file header; return image size and component count. }
{METHODDEF}
procedure start_input_tga (cinfo : j_compress_ptr;
sinfo : cjpeg_source_ptr); far;
var
source : tga_source_ptr;
targaheader : array[0..18-1] of U_CHAR;
idlen, cmaptype, subtype, flags, interlace_type, components : int;
width, height, maplen : uInt;
is_bottom_up : boolean;
var
progress : cd_progress_ptr;
begin
source := tga_source_ptr (sinfo);
if JFREAD(source^.pub.input_file, @targaheader, 18) <> size_t(18) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
{ Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway }
if (targaheader[16] = 15) then
targaheader[16] := 16;
idlen := UCH(targaheader[0]);
cmaptype := UCH(targaheader[1]);
subtype := UCH(targaheader[2]);
maplen := {GET_2B(5);}
uInt (UCH(targaheader[5])) +
( uInt (UCH(targaheader[5+1])) ) shl 8;
width := {GET_2B(12);}
( uInt(UCH(targaheader[12])) +
( uInt(UCH(targaheader[12+1])) ) shl 8);
height := {GET_2B(14);}
( uInt(UCH(targaheader[14])) +
( uInt(UCH(targaheader[14+1])) ) shl 8);
source^.pixel_size := UCH(targaheader[16]) shl 3;
flags := UCH(targaheader[17]); { Image Descriptor byte }
is_bottom_up := (flags and $20) = 0; { bit 5 set => top-down }
interlace_type := flags shl 6; { bits 6/7 are interlace code }
if (cmaptype > 1) or { cmaptype must be 0 or 1 }
(source^.pixel_size < 1) or (source^.pixel_size > 4) or
((UCH(targaheader[16]) and 7) <> 0) or { bits/pixel must be multiple of 8 }
(interlace_type <> 0) then { currently don't allow interlaced image }
ERREXIT(j_common_ptr(cinfo), JERR_TGA_BADPARMS);
if (subtype > 8) then
begin
{ It's an RLE-coded file }
source^.read_pixel := read_rle_pixel;
source^.block_count := 0;
source^.dup_pixel_count := 0;
Dec(subtype, 8);
end
else
begin
{ Non-RLE file }
source^.read_pixel := read_non_rle_pixel;
end;
{ Now should have subtype 1, 2, or 3 }
components := 3; { until proven different }
cinfo^.in_color_space := JCS_RGB;
case (subtype) of
1:begin { Colormapped image }
if (source^.pixel_size = 1) and (cmaptype = 1) then
source^.get_pixel_rows := get_8bit_row
else
ERREXIT(j_common_ptr(cinfo), JERR_TGA_BADPARMS);
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_TGA_MAPPED, width, height);
end;
2:begin { RGB image }
case (source^.pixel_size) of
2: source^.get_pixel_rows := get_16bit_row;
3: source^.get_pixel_rows := get_24bit_row;
4: source^.get_pixel_rows := get_32bit_row;
else
ERREXIT(j_common_ptr(cinfo), JERR_TGA_BADPARMS);
end;
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_TGA, width, height);
end;
3:begin { Grayscale image }
components := 1;
cinfo^.in_color_space := JCS_GRAYSCALE;
if (source^.pixel_size = 1) then
source^.get_pixel_rows := get_8bit_gray_row
else
ERREXIT(j_common_ptr(cinfo), JERR_TGA_BADPARMS);
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_TGA_GRAY, width, height);
end;
else
ERREXIT(j_common_ptr(cinfo), JERR_TGA_BADPARMS);
end;
if (is_bottom_up) then
begin
{ Create a virtual array to buffer the upside-down image. }
source^.whole_image := cinfo^.mem^.request_virt_sarray
(j_common_ptr (cinfo), JPOOL_IMAGE, FALSE,
JDIMENSION(width * components), JDIMENSION (height), JDIMENSION (1));
if (cinfo^.progress <> NIL) then
begin
progress := cd_progress_ptr (cinfo^.progress);
Inc(progress^.total_extra_passes); { count file input as separate pass }
end;
{ source^.pub.buffer will point to the virtual array. }
source^.pub.buffer_height := 1; { in case anyone looks at it }
source^.pub.get_pixel_rows := preload_image;
end
else
begin
{ Don't need a virtual array, but do need a one-row input buffer. }
source^.whole_image := NIL;
source^.pub.buffer := cinfo^.mem^.alloc_sarray (
j_common_ptr (cinfo), JPOOL_IMAGE,
JDIMENSION (width * components), JDIMENSION (1)) ;
source^.pub.buffer_height := 1;
source^.pub.get_pixel_rows := source^.get_pixel_rows;
end;
while (idlen > 0) do { Throw away ID field }
begin
Dec(idlen);
{void} read_byte(source);
end;
if (maplen > 0) then
begin
if (maplen > 256) or {GET_2B(3) <> 0}
( (uInt (UCH(targaheader[3])) +
(uInt (UCH(targaheader[3+1])) ) shl 8) <> 0) then
ERREXIT(j_common_ptr(cinfo), JERR_TGA_BADCMAP);
{ Allocate space to store the colormap }
source^.colormap := cinfo^.mem^.alloc_sarray (
j_common_ptr (cinfo), JPOOL_IMAGE,
JDIMENSION (maplen), JDIMENSION (3));
{ and read it from the file }
read_colormap(source, int (maplen), UCH(targaheader[7]));
end
else
begin
if (cmaptype <> 0) then { but you promised a cmap! }
ERREXIT(j_common_ptr(cinfo), JERR_TGA_BADPARMS);
source^.colormap := NIL;
end;
cinfo^.input_components := components;
cinfo^.data_precision := 8;
cinfo^.image_width := width;
cinfo^.image_height := height;
end;
{ Finish up at the end of the file. }
{METHODDEF}
procedure finish_input_tga (cinfo : j_compress_ptr;
sinfo : cjpeg_source_ptr); far;
begin
{ no work }
end;
{ The module selection routine for Targa format input. }
{GLOBAL}
function jinit_read_targa (cinfo : j_compress_ptr) : cjpeg_source_ptr;
var
source : tga_source_ptr;
begin
{ Create module interface object }
source := tga_source_ptr (
cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE,
SIZEOF(tga_source_struct)) );
source^.cinfo := cinfo; { make back link for subroutines }
{ Fill in method ptrs, except get_pixel_rows which start_input sets }
source^.pub.start_input := start_input_tga;
source^.pub.finish_input := finish_input_tga;
jinit_read_targa := cjpeg_source_ptr (source);
end;
end. { TARGA_SUPPORTED }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -