wrtarga.c
上传用户:wuyixingx
上传日期:2007-01-08
资源大小:745k
文件大小:8k
源码类别:

图形图象

开发平台:

C/C++

  1. /*
  2.  * wrtarga.c
  3.  *
  4.  * Copyright (C) 1991-1996, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to write output images in Targa format.
  9.  *
  10.  * These routines may need modification for non-Unix environments or
  11.  * specialized applications.  As they stand, they assume output to
  12.  * an ordinary stdio stream.
  13.  *
  14.  * Based on code contributed by Lee Daniel Crocker.
  15.  */
  16. #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
  17. #ifdef TARGA_SUPPORTED
  18. /*
  19.  * To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
  20.  * This is not yet implemented.
  21.  */
  22. #if BITS_IN_JSAMPLE != 8
  23.   Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
  24. #endif
  25. /*
  26.  * The output buffer needs to be writable by fwrite().  On PCs, we must
  27.  * allocate the buffer in near data space, because we are assuming small-data
  28.  * memory model, wherein fwrite() can't reach far memory.  If you need to
  29.  * process very wide images on a PC, you might have to compile in large-memory
  30.  * model, or else replace fwrite() with a putc() loop --- which will be much
  31.  * slower.
  32.  */
  33. /* Private version of data destination object */
  34. typedef struct {
  35.   struct djpeg_dest_struct pub; /* public fields */
  36.   char *iobuffer; /* physical I/O buffer */
  37.   JDIMENSION buffer_width; /* width of one row */
  38. } tga_dest_struct;
  39. typedef tga_dest_struct * tga_dest_ptr;
  40. LOCAL(void)
  41. write_header (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, int num_colors)
  42. /* Create and write a Targa header */
  43. {
  44.   char targaheader[18];
  45.   /* Set unused fields of header to 0 */
  46.   MEMZERO(targaheader, SIZEOF(targaheader));
  47.   if (num_colors > 0) {
  48.     targaheader[1] = 1; /* color map type 1 */
  49.     targaheader[5] = (char) (num_colors & 0xFF);
  50.     targaheader[6] = (char) (num_colors >> 8);
  51.     targaheader[7] = 24; /* 24 bits per cmap entry */
  52.   }
  53.   targaheader[12] = (char) (cinfo->output_width & 0xFF);
  54.   targaheader[13] = (char) (cinfo->output_width >> 8);
  55.   targaheader[14] = (char) (cinfo->output_height & 0xFF);
  56.   targaheader[15] = (char) (cinfo->output_height >> 8);
  57.   targaheader[17] = 0x20; /* Top-down, non-interlaced */
  58.   if (cinfo->out_color_space == JCS_GRAYSCALE) {
  59.     targaheader[2] = 3; /* image type = uncompressed gray-scale */
  60.     targaheader[16] = 8; /* bits per pixel */
  61.   } else { /* must be RGB */
  62.     if (num_colors > 0) {
  63.       targaheader[2] = 1; /* image type = colormapped RGB */
  64.       targaheader[16] = 8;
  65.     } else {
  66.       targaheader[2] = 2; /* image type = uncompressed RGB */
  67.       targaheader[16] = 24;
  68.     }
  69.   }
  70.   if (JFWRITE(dinfo->output_file, targaheader, 18) != (size_t) 18)
  71.     ERREXIT(cinfo, JERR_FILE_WRITE);
  72. }
  73. /*
  74.  * Write some pixel data.
  75.  * In this module rows_supplied will always be 1.
  76.  */
  77. METHODDEF(void)
  78. put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
  79. JDIMENSION rows_supplied)
  80. /* used for unquantized full-color output */
  81. {
  82.   tga_dest_ptr dest = (tga_dest_ptr) dinfo;
  83.   register JSAMPROW inptr;
  84.   register char * outptr;
  85.   register JDIMENSION col;
  86.   inptr = dest->pub.buffer[0];
  87.   outptr = dest->iobuffer;
  88.   for (col = cinfo->output_width; col > 0; col--) {
  89.     outptr[0] = (char) GETJSAMPLE(inptr[2]); /* RGB to BGR order */
  90.     outptr[1] = (char) GETJSAMPLE(inptr[1]);
  91.     outptr[2] = (char) GETJSAMPLE(inptr[0]);
  92.     inptr += 3, outptr += 3;
  93.   }
  94.   (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
  95. }
  96. METHODDEF(void)
  97. put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
  98.        JDIMENSION rows_supplied)
  99. /* used for grayscale OR quantized color output */
  100. {
  101.   tga_dest_ptr dest = (tga_dest_ptr) dinfo;
  102.   register JSAMPROW inptr;
  103.   register char * outptr;
  104.   register JDIMENSION col;
  105.   inptr = dest->pub.buffer[0];
  106.   outptr = dest->iobuffer;
  107.   for (col = cinfo->output_width; col > 0; col--) {
  108.     *outptr++ = (char) GETJSAMPLE(*inptr++);
  109.   }
  110.   (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
  111. }
  112. /*
  113.  * Write some demapped pixel data when color quantization is in effect.
  114.  * For Targa, this is only applied to grayscale data.
  115.  */
  116. METHODDEF(void)
  117. put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
  118.    JDIMENSION rows_supplied)
  119. {
  120.   tga_dest_ptr dest = (tga_dest_ptr) dinfo;
  121.   register JSAMPROW inptr;
  122.   register char * outptr;
  123.   register JSAMPROW color_map0 = cinfo->colormap[0];
  124.   register JDIMENSION col;
  125.   inptr = dest->pub.buffer[0];
  126.   outptr = dest->iobuffer;
  127.   for (col = cinfo->output_width; col > 0; col--) {
  128.     *outptr++ = (char) GETJSAMPLE(color_map0[GETJSAMPLE(*inptr++)]);
  129.   }
  130.   (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
  131. }
  132. /*
  133.  * Startup: write the file header.
  134.  */
  135. METHODDEF(void)
  136. start_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
  137. {
  138.   tga_dest_ptr dest = (tga_dest_ptr) dinfo;
  139.   int num_colors, i;
  140.   FILE *outfile;
  141.   if (cinfo->out_color_space == JCS_GRAYSCALE) {
  142.     /* Targa doesn't have a mapped grayscale format, so we will */
  143.     /* demap quantized gray output.  Never emit a colormap. */
  144.     write_header(cinfo, dinfo, 0);
  145.     if (cinfo->quantize_colors)
  146.       dest->pub.put_pixel_rows = put_demapped_gray;
  147.     else
  148.       dest->pub.put_pixel_rows = put_gray_rows;
  149.   } else if (cinfo->out_color_space == JCS_RGB) {
  150.     if (cinfo->quantize_colors) {
  151.       /* We only support 8-bit colormap indexes, so only 256 colors */
  152.       num_colors = cinfo->actual_number_of_colors;
  153.       if (num_colors > 256)
  154. ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, num_colors);
  155.       write_header(cinfo, dinfo, num_colors);
  156.       /* Write the colormap.  Note Targa uses BGR byte order */
  157.       outfile = dest->pub.output_file;
  158.       for (i = 0; i < num_colors; i++) {
  159. putc(GETJSAMPLE(cinfo->colormap[2][i]), outfile);
  160. putc(GETJSAMPLE(cinfo->colormap[1][i]), outfile);
  161. putc(GETJSAMPLE(cinfo->colormap[0][i]), outfile);
  162.       }
  163.       dest->pub.put_pixel_rows = put_gray_rows;
  164.     } else {
  165.       write_header(cinfo, dinfo, 0);
  166.       dest->pub.put_pixel_rows = put_pixel_rows;
  167.     }
  168.   } else {
  169.     ERREXIT(cinfo, JERR_TGA_COLORSPACE);
  170.   }
  171. }
  172. /*
  173.  * Finish up at the end of the file.
  174.  */
  175. METHODDEF(void)
  176. finish_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
  177. {
  178.   /* Make sure we wrote the output file OK */
  179.   fflush(dinfo->output_file);
  180.   if (ferror(dinfo->output_file))
  181.     ERREXIT(cinfo, JERR_FILE_WRITE);
  182. }
  183. /*
  184.  * The module selection routine for Targa format output.
  185.  */
  186. GLOBAL(djpeg_dest_ptr)
  187. jinit_write_targa (j_decompress_ptr cinfo)
  188. {
  189.   tga_dest_ptr dest;
  190.   /* Create module interface object, fill in method pointers */
  191.   dest = (tga_dest_ptr)
  192.       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  193.   SIZEOF(tga_dest_struct));
  194.   dest->pub.start_output = start_output_tga;
  195.   dest->pub.finish_output = finish_output_tga;
  196.   /* Calculate output image dimensions so we can allocate space */
  197.   jpeg_calc_output_dimensions(cinfo);
  198.   /* Create I/O buffer.  Note we make this near on a PC. */
  199.   dest->buffer_width = cinfo->output_width * cinfo->output_components;
  200.   dest->iobuffer = (char *)
  201.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  202. (size_t) (dest->buffer_width * SIZEOF(char)));
  203.   /* Create decompressor output buffer. */
  204.   dest->pub.buffer = (*cinfo->mem->alloc_sarray)
  205.     ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width, (JDIMENSION) 1);
  206.   dest->pub.buffer_height = 1;
  207.   return (djpeg_dest_ptr) dest;
  208. }
  209. #endif /* TARGA_SUPPORTED */