Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
13 KiB

  1. /*
  2. * wrgif.c
  3. *
  4. * Copyright (C) 1991-1997, 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 GIF format.
  9. *
  10. **************************************************************************
  11. * NOTE: to avoid entanglements with Unisys' patent on LZW compression, *
  12. * this code has been modified to output "uncompressed GIF" files. *
  13. * There is no trace of the LZW algorithm in this file. *
  14. **************************************************************************
  15. *
  16. * These routines may need modification for non-Unix environments or
  17. * specialized applications. As they stand, they assume output to
  18. * an ordinary stdio stream.
  19. */
  20. /*
  21. * This code is loosely based on ppmtogif from the PBMPLUS distribution
  22. * of Feb. 1991. That file contains the following copyright notice:
  23. * Based on GIFENCODE by David Rowley <mgardi@watdscu.waterloo.edu>.
  24. * Lempel-Ziv compression based on "compress" by Spencer W. Thomas et al.
  25. * Copyright (C) 1989 by Jef Poskanzer.
  26. * Permission to use, copy, modify, and distribute this software and its
  27. * documentation for any purpose and without fee is hereby granted, provided
  28. * that the above copyright notice appear in all copies and that both that
  29. * copyright notice and this permission notice appear in supporting
  30. * documentation. This software is provided "as is" without express or
  31. * implied warranty.
  32. *
  33. * We are also required to state that
  34. * "The Graphics Interchange Format(c) is the Copyright property of
  35. * CompuServe Incorporated. GIF(sm) is a Service Mark property of
  36. * CompuServe Incorporated."
  37. */
  38. #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
  39. #ifdef GIF_SUPPORTED
  40. /* Private version of data destination object */
  41. typedef struct {
  42. struct djpeg_dest_struct pub; /* public fields */
  43. j_decompress_ptr cinfo; /* back link saves passing separate parm */
  44. /* State for packing variable-width codes into a bitstream */
  45. int n_bits; /* current number of bits/code */
  46. int maxcode; /* maximum code, given n_bits */
  47. INT32 cur_accum; /* holds bits not yet output */
  48. int cur_bits; /* # of bits in cur_accum */
  49. /* State for GIF code assignment */
  50. int ClearCode; /* clear code (doesn't change) */
  51. int EOFCode; /* EOF code (ditto) */
  52. int code_counter; /* counts output symbols */
  53. /* GIF data packet construction buffer */
  54. int bytesinpkt; /* # of bytes in current packet */
  55. char packetbuf[256]; /* workspace for accumulating packet */
  56. } gif_dest_struct;
  57. typedef gif_dest_struct * gif_dest_ptr;
  58. /* Largest value that will fit in N bits */
  59. #define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
  60. /*
  61. * Routines to package finished data bytes into GIF data blocks.
  62. * A data block consists of a count byte (1..255) and that many data bytes.
  63. */
  64. LOCAL(void)
  65. flush_packet (gif_dest_ptr dinfo)
  66. /* flush any accumulated data */
  67. {
  68. if (dinfo->bytesinpkt > 0) { /* never write zero-length packet */
  69. dinfo->packetbuf[0] = (char) dinfo->bytesinpkt++;
  70. if (JFWRITE(dinfo->pub.output_file, dinfo->packetbuf, dinfo->bytesinpkt)
  71. != (size_t) dinfo->bytesinpkt)
  72. ERREXIT(dinfo->cinfo, JERR_FILE_WRITE);
  73. dinfo->bytesinpkt = 0;
  74. }
  75. }
  76. /* Add a character to current packet; flush to disk if necessary */
  77. #define CHAR_OUT(dinfo,c) \
  78. { (dinfo)->packetbuf[++(dinfo)->bytesinpkt] = (char) (c); \
  79. if ((dinfo)->bytesinpkt >= 255) \
  80. flush_packet(dinfo); \
  81. }
  82. /* Routine to convert variable-width codes into a byte stream */
  83. LOCAL(void)
  84. output (gif_dest_ptr dinfo, int code)
  85. /* Emit a code of n_bits bits */
  86. /* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
  87. {
  88. dinfo->cur_accum |= ((INT32) code) << dinfo->cur_bits;
  89. dinfo->cur_bits += dinfo->n_bits;
  90. while (dinfo->cur_bits >= 8) {
  91. CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF);
  92. dinfo->cur_accum >>= 8;
  93. dinfo->cur_bits -= 8;
  94. }
  95. }
  96. /* The pseudo-compression algorithm.
  97. *
  98. * In this module we simply output each pixel value as a separate symbol;
  99. * thus, no compression occurs. In fact, there is expansion of one bit per
  100. * pixel, because we use a symbol width one bit wider than the pixel width.
  101. *
  102. * GIF ordinarily uses variable-width symbols, and the decoder will expect
  103. * to ratchet up the symbol width after a fixed number of symbols.
  104. * To simplify the logic and keep the expansion penalty down, we emit a
  105. * GIF Clear code to reset the decoder just before the width would ratchet up.
  106. * Thus, all the symbols in the output file will have the same bit width.
  107. * Note that emitting the Clear codes at the right times is a mere matter of
  108. * counting output symbols and is in no way dependent on the LZW patent.
  109. *
  110. * With a small basic pixel width (low color count), Clear codes will be
  111. * needed very frequently, causing the file to expand even more. So this
  112. * simplistic approach wouldn't work too well on bilevel images, for example.
  113. * But for output of JPEG conversions the pixel width will usually be 8 bits
  114. * (129 to 256 colors), so the overhead added by Clear symbols is only about
  115. * one symbol in every 256.
  116. */
  117. LOCAL(void)
  118. compress_init (gif_dest_ptr dinfo, int i_bits)
  119. /* Initialize pseudo-compressor */
  120. {
  121. /* init all the state variables */
  122. dinfo->n_bits = i_bits;
  123. dinfo->maxcode = MAXCODE(dinfo->n_bits);
  124. dinfo->ClearCode = (1 << (i_bits - 1));
  125. dinfo->EOFCode = dinfo->ClearCode + 1;
  126. dinfo->code_counter = dinfo->ClearCode + 2;
  127. /* init output buffering vars */
  128. dinfo->bytesinpkt = 0;
  129. dinfo->cur_accum = 0;
  130. dinfo->cur_bits = 0;
  131. /* GIF specifies an initial Clear code */
  132. output(dinfo, dinfo->ClearCode);
  133. }
  134. LOCAL(void)
  135. compress_pixel (gif_dest_ptr dinfo, int c)
  136. /* Accept and "compress" one pixel value.
  137. * The given value must be less than n_bits wide.
  138. */
  139. {
  140. /* Output the given pixel value as a symbol. */
  141. output(dinfo, c);
  142. /* Issue Clear codes often enough to keep the reader from ratcheting up
  143. * its symbol size.
  144. */
  145. if (dinfo->code_counter < dinfo->maxcode) {
  146. dinfo->code_counter++;
  147. } else {
  148. output(dinfo, dinfo->ClearCode);
  149. dinfo->code_counter = dinfo->ClearCode + 2; /* reset the counter */
  150. }
  151. }
  152. LOCAL(void)
  153. compress_term (gif_dest_ptr dinfo)
  154. /* Clean up at end */
  155. {
  156. /* Send an EOF code */
  157. output(dinfo, dinfo->EOFCode);
  158. /* Flush the bit-packing buffer */
  159. if (dinfo->cur_bits > 0) {
  160. CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF);
  161. }
  162. /* Flush the packet buffer */
  163. flush_packet(dinfo);
  164. }
  165. /* GIF header construction */
  166. LOCAL(void)
  167. put_word (gif_dest_ptr dinfo, unsigned int w)
  168. /* Emit a 16-bit word, LSB first */
  169. {
  170. putc(w & 0xFF, dinfo->pub.output_file);
  171. putc((w >> 8) & 0xFF, dinfo->pub.output_file);
  172. }
  173. LOCAL(void)
  174. put_3bytes (gif_dest_ptr dinfo, int val)
  175. /* Emit 3 copies of same byte value --- handy subr for colormap construction */
  176. {
  177. putc(val, dinfo->pub.output_file);
  178. putc(val, dinfo->pub.output_file);
  179. putc(val, dinfo->pub.output_file);
  180. }
  181. LOCAL(void)
  182. emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap)
  183. /* Output the GIF file header, including color map */
  184. /* If colormap==NULL, synthesize a gray-scale colormap */
  185. {
  186. int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte;
  187. int cshift = dinfo->cinfo->data_precision - 8;
  188. int i;
  189. if (num_colors > 256)
  190. ERREXIT1(dinfo->cinfo, JERR_TOO_MANY_COLORS, num_colors);
  191. /* Compute bits/pixel and related values */
  192. BitsPerPixel = 1;
  193. while (num_colors > (1 << BitsPerPixel))
  194. BitsPerPixel++;
  195. ColorMapSize = 1 << BitsPerPixel;
  196. if (BitsPerPixel <= 1)
  197. InitCodeSize = 2;
  198. else
  199. InitCodeSize = BitsPerPixel;
  200. /*
  201. * Write the GIF header.
  202. * Note that we generate a plain GIF87 header for maximum compatibility.
  203. */
  204. putc('G', dinfo->pub.output_file);
  205. putc('I', dinfo->pub.output_file);
  206. putc('F', dinfo->pub.output_file);
  207. putc('8', dinfo->pub.output_file);
  208. putc('7', dinfo->pub.output_file);
  209. putc('a', dinfo->pub.output_file);
  210. /* Write the Logical Screen Descriptor */
  211. put_word(dinfo, (unsigned int) dinfo->cinfo->output_width);
  212. put_word(dinfo, (unsigned int) dinfo->cinfo->output_height);
  213. FlagByte = 0x80; /* Yes, there is a global color table */
  214. FlagByte |= (BitsPerPixel-1) << 4; /* color resolution */
  215. FlagByte |= (BitsPerPixel-1); /* size of global color table */
  216. putc(FlagByte, dinfo->pub.output_file);
  217. putc(0, dinfo->pub.output_file); /* Background color index */
  218. putc(0, dinfo->pub.output_file); /* Reserved (aspect ratio in GIF89) */
  219. /* Write the Global Color Map */
  220. /* If the color map is more than 8 bits precision, */
  221. /* we reduce it to 8 bits by shifting */
  222. for (i=0; i < ColorMapSize; i++) {
  223. if (i < num_colors) {
  224. if (colormap != NULL) {
  225. if (dinfo->cinfo->out_color_space == JCS_RGB) {
  226. /* Normal case: RGB color map */
  227. putc(GETJSAMPLE(colormap[0][i]) >> cshift, dinfo->pub.output_file);
  228. putc(GETJSAMPLE(colormap[1][i]) >> cshift, dinfo->pub.output_file);
  229. putc(GETJSAMPLE(colormap[2][i]) >> cshift, dinfo->pub.output_file);
  230. } else {
  231. /* Grayscale "color map": possible if quantizing grayscale image */
  232. put_3bytes(dinfo, GETJSAMPLE(colormap[0][i]) >> cshift);
  233. }
  234. } else {
  235. /* Create a gray-scale map of num_colors values, range 0..255 */
  236. put_3bytes(dinfo, (i * 255 + (num_colors-1)/2) / (num_colors-1));
  237. }
  238. } else {
  239. /* fill out the map to a power of 2 */
  240. put_3bytes(dinfo, 0);
  241. }
  242. }
  243. /* Write image separator and Image Descriptor */
  244. putc(',', dinfo->pub.output_file); /* separator */
  245. put_word(dinfo, 0); /* left/top offset */
  246. put_word(dinfo, 0);
  247. put_word(dinfo, (unsigned int) dinfo->cinfo->output_width); /* image size */
  248. put_word(dinfo, (unsigned int) dinfo->cinfo->output_height);
  249. /* flag byte: not interlaced, no local color map */
  250. putc(0x00, dinfo->pub.output_file);
  251. /* Write Initial Code Size byte */
  252. putc(InitCodeSize, dinfo->pub.output_file);
  253. /* Initialize for "compression" of image data */
  254. compress_init(dinfo, InitCodeSize+1);
  255. }
  256. /*
  257. * Startup: write the file header.
  258. */
  259. METHODDEF(void)
  260. start_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
  261. {
  262. gif_dest_ptr dest = (gif_dest_ptr) dinfo;
  263. if (cinfo->quantize_colors)
  264. emit_header(dest, cinfo->actual_number_of_colors, cinfo->colormap);
  265. else
  266. emit_header(dest, 256, (JSAMPARRAY) NULL);
  267. }
  268. /*
  269. * Write some pixel data.
  270. * In this module rows_supplied will always be 1.
  271. */
  272. METHODDEF(void)
  273. put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
  274. JDIMENSION rows_supplied)
  275. {
  276. gif_dest_ptr dest = (gif_dest_ptr) dinfo;
  277. register JSAMPROW ptr;
  278. register JDIMENSION col;
  279. ptr = dest->pub.buffer[0];
  280. for (col = cinfo->output_width; col > 0; col--) {
  281. compress_pixel(dest, GETJSAMPLE(*ptr++));
  282. }
  283. }
  284. /*
  285. * Finish up at the end of the file.
  286. */
  287. METHODDEF(void)
  288. finish_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
  289. {
  290. gif_dest_ptr dest = (gif_dest_ptr) dinfo;
  291. /* Flush "compression" mechanism */
  292. compress_term(dest);
  293. /* Write a zero-length data block to end the series */
  294. putc(0, dest->pub.output_file);
  295. /* Write the GIF terminator mark */
  296. putc(';', dest->pub.output_file);
  297. /* Make sure we wrote the output file OK */
  298. fflush(dest->pub.output_file);
  299. if (ferror(dest->pub.output_file))
  300. ERREXIT(cinfo, JERR_FILE_WRITE);
  301. }
  302. /*
  303. * The module selection routine for GIF format output.
  304. */
  305. GLOBAL(djpeg_dest_ptr)
  306. jinit_write_gif (j_decompress_ptr cinfo)
  307. {
  308. gif_dest_ptr dest;
  309. /* Create module interface object, fill in method pointers */
  310. dest = (gif_dest_ptr)
  311. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  312. SIZEOF(gif_dest_struct));
  313. dest->cinfo = cinfo; /* make back link for subroutines */
  314. dest->pub.start_output = start_output_gif;
  315. dest->pub.put_pixel_rows = put_pixel_rows;
  316. dest->pub.finish_output = finish_output_gif;
  317. if (cinfo->out_color_space != JCS_GRAYSCALE &&
  318. cinfo->out_color_space != JCS_RGB)
  319. ERREXIT(cinfo, JERR_GIF_COLORSPACE);
  320. /* Force quantization if color or if > 8 bits input */
  321. if (cinfo->out_color_space != JCS_GRAYSCALE || cinfo->data_precision > 8) {
  322. /* Force quantization to at most 256 colors */
  323. cinfo->quantize_colors = TRUE;
  324. if (cinfo->desired_number_of_colors > 256)
  325. cinfo->desired_number_of_colors = 256;
  326. }
  327. /* Calculate output image dimensions so we can allocate space */
  328. jpeg_calc_output_dimensions(cinfo);
  329. if (cinfo->output_components != 1) /* safety check: just one component? */
  330. ERREXIT(cinfo, JERR_GIF_BUG);
  331. /* Create decompressor output buffer. */
  332. dest->pub.buffer = (*cinfo->mem->alloc_sarray)
  333. ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->output_width, (JDIMENSION) 1);
  334. dest->pub.buffer_height = 1;
  335. return (djpeg_dest_ptr) dest;
  336. }
  337. #endif /* GIF_SUPPORTED */