123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- Unit wrtarga;
- { Copyright (C) 1991-1996, Thomas G. Lane.
- Based on code contributed by Lee Daniel Crocker.
- This file contains routines to write output images in Targa format. }
- interface
- {$I jconfig.inc}
- uses
- jmorecfg,
- jpeglib,
- jdeferr,
- jerror,
- jinclude,
- jdmaster,
- cdjpeg; { Common decls for cjpeg/djpeg applications }
- function jinit_write_targa (cinfo : j_decompress_ptr) : djpeg_dest_ptr;
- implementation
- { To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
- This is not yet implemented. }
- {$ifndef BITS_IN_JSAMPLE_IS_8}
- Sorry, this code only copes with 8-bit JSAMPLEs. { deliberate syntax err }
- {$endif}
- { The output buffer needs to be writable by fwrite(). On PCs, we must
- allocate the buffer in near data space, because we are assuming small-data
- memory model, wherein fwrite() can't reach far memory. If you need to
- process very wide images on a PC, you might have to compile in large-memory
- model, or else replace fwrite() with a putc() loop --- which will be much
- slower. }
- { Private version of data destination object }
- type
- tga_dest_ptr = ^tga_dest_struct;
- tga_dest_struct = record
- pub : djpeg_dest_struct; { public fields }
- iobuffer : byteptr; { physical I/O buffer }
- buffer_width : JDIMENSION; { width of one row }
- end;
- {LOCAL}
- procedure write_header (cinfo : j_decompress_ptr;
- dinfo : djpeg_dest_ptr;
- num_colors : int);
- { Create and write a Targa header }
- var
- targaheader : array[0..18-1] of byte;
- begin
- { Set unused fields of header to 0 }
- MEMZERO(@targaheader, SIZEOF(targaheader));
- if (num_colors > 0) then
- begin
- targaheader[1] := 1; { color map type 1 }
- targaheader[5] := byte (num_colors and $FF);
- targaheader[6] := byte (num_colors shr 8);
- targaheader[7] := 24; { 24 bits per cmap entry }
- end;
- targaheader[12] := byte (cinfo^.output_width and $FF);
- targaheader[13] := byte (cinfo^.output_width shr 8);
- targaheader[14] := byte (cinfo^.output_height and $FF);
- targaheader[15] := byte (cinfo^.output_height shr 8);
- targaheader[17] := $20; { Top-down, non-interlaced }
- if (cinfo^.out_color_space = JCS_GRAYSCALE) then
- begin
- targaheader[2] := 3; { image type := uncompressed gray-scale }
- targaheader[16] := 8; { bits per pixel }
- end
- else
- begin { must be RGB }
- if (num_colors > 0) then
- begin
- targaheader[2] := 1; { image type = colormapped RGB }
- targaheader[16] := 8;
- end
- else
- begin
- targaheader[2] := 2; { image type = uncompressed RGB }
- targaheader[16] := 24;
- end;
- end;
- if (JFWRITE(dinfo^.output_file, @targaheader, 18) <> size_t (18)) then
- ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);
- end;
- { Write some pixel data.
- In this module rows_supplied will always be 1. }
- {METHODDEF}
- procedure put_pixel_rows (cinfo : j_decompress_ptr;
- dinfo : djpeg_dest_ptr;
- rows_supplied : JDIMENSION); far;
- { used for unquantized full-color output }
- var
- dest : tga_dest_ptr;
- {register} inptr : RGBptr;
- {register} outptr : BGRptr;
- {register} col : JDIMENSION;
- begin
- dest := tga_dest_ptr (dinfo);
- inptr := RGBptr(dest^.pub.buffer^[0]);
- outptr := BGRptr(dest^.iobuffer);
- for col := pred(cinfo^.output_width) downto 0 do
- begin
- outptr^.b := byte (GETJSAMPLE(inptr^.b)); { RGB to BGR order }
- outptr^.g := byte (GETJSAMPLE(inptr^.g));
- outptr^.r := byte (GETJSAMPLE(inptr^.r));
- Inc(inptr);
- Inc(outptr);
- end;
- {void} JFWRITE(dest^.pub.output_file, dest^.iobuffer, dest^.buffer_width);
- end;
- {METHODDEF}
- procedure put_gray_rows (cinfo : j_decompress_ptr;
- dinfo : djpeg_dest_ptr;
- rows_supplied : JDIMENSION); far;
- { used for grayscale OR quantized color output }
- var
- dest : tga_dest_ptr;
- {register} inptr : JSAMPLE_PTR;
- {register} outptr : byteptr;
- {register} col : JDIMENSION;
- begin
- dest := tga_dest_ptr (dinfo);
- inptr := JSAMPLE_PTR(dest^.pub.buffer^[0]);
- outptr := dest^.iobuffer;
- for col := pred(cinfo^.output_width) downto 0 do
- begin
- outptr^ := byte( GETJSAMPLE(inptr^) );
- Inc(inptr);
- Inc(outptr);
- end;
- {void} JFWRITE(dest^.pub.output_file, dest^.iobuffer, dest^.buffer_width);
- end;
- { Write some demapped pixel data when color quantization is in effect.
- For Targa, this is only applied to grayscale data. }
- {METHODDEF}
- procedure put_demapped_gray (cinfo : j_decompress_ptr;
- dinfo : djpeg_dest_ptr;
- rows_supplied : JDIMENSION); far;
- var
- dest : tga_dest_ptr;
- {register} inptr : JSAMPLE_PTR;
- {register} outptr : byteptr;
- {register} color_map0 : JSAMPROW;
- {register} col : JDIMENSION;
- begin
- dest := tga_dest_ptr (dinfo);
- color_map0 := cinfo^.colormap^[0];
- inptr := JSAMPLE_PTR(dest^.pub.buffer^[0]);
- outptr := dest^.iobuffer;
- for col := pred(cinfo^.output_width) downto 0 do
- begin
- outptr^ := byte( GETJSAMPLE(color_map0^[GETJSAMPLE(inptr^)]) );
- Inc(inptr);
- Inc(outptr);
- end;
- {void} JFWRITE(dest^.pub.output_file, dest^.iobuffer, dest^.buffer_width);
- end;
- { Startup: write the file header. }
- {METHODDEF}
- procedure start_output_tga (cinfo : j_decompress_ptr;
- dinfo : djpeg_dest_ptr); far;
- var
- dest : tga_dest_ptr;
- num_colors, i : int;
- outfile : FILEptr;
- var
- output_color_map : Array[0..255] of BGRtype;
- begin
- dest := tga_dest_ptr (dinfo);
- if (cinfo^.out_color_space = JCS_GRAYSCALE) then
- begin
- { Targa doesn't have a mapped grayscale format, so we will }
- { demap quantized gray output. Never emit a colormap. }
- write_header(cinfo, dinfo, 0);
- if (cinfo^.quantize_colors) then
- dest^.pub.put_pixel_rows := put_demapped_gray
- else
- dest^.pub.put_pixel_rows := put_gray_rows;
- end
- else
- if (cinfo^.out_color_space = JCS_RGB) then
- begin
- if (cinfo^.quantize_colors) then
- begin
- { We only support 8-bit colormap indexes, so only 256 colors }
- num_colors := cinfo^.actual_number_of_colors;
- if (num_colors > 256) then
- ERREXIT1(j_common_ptr(cinfo), JERR_TOO_MANY_COLORS, num_colors);
- write_header(cinfo, dinfo, num_colors);
- { Write the colormap. Note Targa uses BGR byte order }
- outfile := dest^.pub.output_file;
- for i := 0 to pred(num_colors) do
- begin
- output_color_map[i].b := cinfo^.colormap^[2]^[i];
- output_color_map[i].g := cinfo^.colormap^[1]^[i];
- output_color_map[i].r := cinfo^.colormap^[0]^[i];
- end;
- JFWRITE(outfile, @output_color_map, num_colors*3);
- dest^.pub.put_pixel_rows := put_gray_rows;
- end
- else
- begin
- write_header(cinfo, dinfo, 0);
- dest^.pub.put_pixel_rows := put_pixel_rows;
- end;
- end
- else
- begin
- ERREXIT(j_common_ptr(cinfo), JERR_TGA_COLORSPACE);
- end;
- end;
- { Finish up at the end of the file. }
- {METHODDEF}
- procedure finish_output_tga (cinfo : j_decompress_ptr;
- dinfo : djpeg_dest_ptr); far;
- begin
- { Make sure we wrote the output file OK }
- {fflush(dinfo^.output_file^);
- if (ferror(dinfo^.output_file)) then
- ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);
- }
- end;
- { The module selection routine for Targa format output. }
- {GLOBAL}
- function jinit_write_targa (cinfo : j_decompress_ptr) : djpeg_dest_ptr;
- var
- dest : tga_dest_ptr;
- begin
- { Create module interface object, fill in method pointers }
- dest := tga_dest_ptr(
- cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE,
- SIZEOF(tga_dest_struct)) );
- dest^.pub.start_output := start_output_tga;
- dest^.pub.finish_output := finish_output_tga;
- { Calculate output image dimensions so we can allocate space }
- jpeg_calc_output_dimensions(cinfo);
- { Create I/O buffer. Note we make this near on a PC. }
- dest^.buffer_width := cinfo^.output_width * cinfo^.output_components;
- dest^.iobuffer := byteptr(
- cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE,
- size_t (dest^.buffer_width * SIZEOF(byte))));
- { Create decompressor output buffer. }
- dest^.pub.buffer := cinfo^.mem^.alloc_sarray
- (j_common_ptr (cinfo), JPOOL_IMAGE, dest^.buffer_width, JDIMENSION (1));
- dest^.pub.buffer_height := 1;
- jinit_write_targa := djpeg_dest_ptr (dest);
- end;
- end. { TARGA_SUPPORTED }
|