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