source: trunk/third/firefox/jpeg/jdatadst.c @ 21695

Revision 21695, 7.1 KB checked in by rbasch, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21694, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * jdatadst.c
3 *
4 * Copyright (C) 1994-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 compression data destination routines for the case of
9 * emitting JPEG data to a file (or any stdio stream).  While these routines
10 * are sufficient for most applications, some will want to use a different
11 * destination manager.
12 * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
13 * JOCTETs into 8-bit-wide elements on external storage.  If char is wider
14 * than 8 bits on your machine, you may need to do some tweaking.
15 */
16
17/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
18#include "jinclude.h"
19#include "jpeglib.h"
20#include "jerror.h"
21
22
23/* Expanded data destination object for stdio output */
24
25typedef struct {
26  struct jpeg_destination_mgr pub; /* public fields */
27
28  FILE * outfile;               /* target stream */
29  JOCTET * buffer;              /* start of buffer */
30} my_destination_mgr;
31
32typedef my_destination_mgr * my_dest_ptr;
33
34#define OUTPUT_BUF_SIZE  4096   /* choose an efficiently fwrite'able size */
35
36
37/*
38 * Initialize destination --- called by jpeg_start_compress
39 * before any data is actually written.
40 */
41
42METHODDEF(void)
43init_destination (j_compress_ptr cinfo)
44{
45  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
46
47  /* Allocate the output buffer --- it will be released when done with image */
48  dest->buffer = (JOCTET *)
49      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
50                                  OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
51
52  dest->pub.next_output_byte = dest->buffer;
53  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
54}
55
56
57/*
58 * Empty the output buffer --- called whenever buffer fills up.
59 *
60 * In typical applications, this should write the entire output buffer
61 * (ignoring the current state of next_output_byte & free_in_buffer),
62 * reset the pointer & count to the start of the buffer, and return TRUE
63 * indicating that the buffer has been dumped.
64 *
65 * In applications that need to be able to suspend compression due to output
66 * overrun, a FALSE return indicates that the buffer cannot be emptied now.
67 * In this situation, the compressor will return to its caller (possibly with
68 * an indication that it has not accepted all the supplied scanlines).  The
69 * application should resume compression after it has made more room in the
70 * output buffer.  Note that there are substantial restrictions on the use of
71 * suspension --- see the documentation.
72 *
73 * When suspending, the compressor will back up to a convenient restart point
74 * (typically the start of the current MCU). next_output_byte & free_in_buffer
75 * indicate where the restart point will be if the current call returns FALSE.
76 * Data beyond this point will be regenerated after resumption, so do not
77 * write it out when emptying the buffer externally.
78 */
79
80METHODDEF(boolean)
81empty_output_buffer (j_compress_ptr cinfo)
82{
83  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
84
85  if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) !=
86      (size_t) OUTPUT_BUF_SIZE)
87    ERREXIT(cinfo, JERR_FILE_WRITE);
88
89  dest->pub.next_output_byte = dest->buffer;
90  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
91
92  return TRUE;
93}
94
95
96/*
97 * Terminate destination --- called by jpeg_finish_compress
98 * after all data has been written.  Usually needs to flush buffer.
99 *
100 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
101 * application must deal with any cleanup that should happen even
102 * for error exit.
103 */
104
105METHODDEF(void)
106term_destination (j_compress_ptr cinfo)
107{
108  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
109  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
110
111  /* Write any data remaining in the buffer */
112  if (datacount > 0) {
113    if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
114      ERREXIT(cinfo, JERR_FILE_WRITE);
115  }
116  fflush(dest->outfile);
117  /* Make sure we wrote the output file OK */
118  if (ferror(dest->outfile))
119    ERREXIT(cinfo, JERR_FILE_WRITE);
120}
121
122
123/*
124 * Prepare for output to a stdio stream.
125 * The caller must have already opened the stream, and is responsible
126 * for closing it after finishing compression.
127 */
128
129GLOBAL(void)
130jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
131{
132  my_dest_ptr dest;
133
134  /* The destination object is made permanent so that multiple JPEG images
135   * can be written to the same file without re-executing jpeg_stdio_dest.
136   * This makes it dangerous to use this manager and a different destination
137   * manager serially with the same JPEG object, because their private object
138   * sizes may be different.  Caveat programmer.
139   */
140  if (cinfo->dest == NULL) {    /* first time for this JPEG object? */
141    cinfo->dest = (struct jpeg_destination_mgr *)
142      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
143                                  SIZEOF(my_destination_mgr));
144  }
145
146  dest = (my_dest_ptr) cinfo->dest;
147  dest->pub.init_destination = init_destination;
148  dest->pub.empty_output_buffer = empty_output_buffer;
149  dest->pub.term_destination = term_destination;
150  dest->outfile = outfile;
151}
152
153/*
154 * term_destination_file_close --- called by jpeg_finish_compress
155 * after all data has been written.  Usually needs to flush buffer.
156 * also will need to close file
157 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
158 * application must deal with any cleanup that should happen even
159 * for error exit.
160 */
161
162METHODDEF(void)
163term_destination_file_close(j_compress_ptr cinfo)
164{
165  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
166  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
167
168  /* Write any data remaining in the buffer */
169  if (datacount > 0) {
170    if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
171      ERREXIT(cinfo, JERR_FILE_WRITE);
172  }
173  fflush(dest->outfile);
174 
175  /* Make sure we wrote the output file OK */
176  if (ferror(dest->outfile))
177    ERREXIT(cinfo, JERR_FILE_WRITE);
178  else
179      fclose(dest->outfile);
180}
181
182
183
184
185
186/*
187 * Prepare for output to a file from a char *
188 * The caller is responsible
189 * for closing it after finishing compression.
190 */
191
192GLOBAL(void)
193jpeg_file_dest (j_compress_ptr cinfo, char * outfile)
194{
195  my_dest_ptr dest;
196
197  /* The destination object is made permanent so that multiple JPEG images
198   * can be written to the same file without re-executing jpeg_stdio_dest.
199   * This makes it dangerous to use this manager and a different destination
200   * manager serially with the same JPEG object, because their private object
201   * sizes may be different.  Caveat programmer.
202   */
203  if (cinfo->dest == NULL) {    /* first time for this JPEG object? */
204    cinfo->dest = (struct jpeg_destination_mgr *)
205      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
206                                  SIZEOF(my_destination_mgr));
207  }
208
209  dest = (my_dest_ptr) cinfo->dest;
210  dest->pub.init_destination = init_destination;
211  dest->pub.empty_output_buffer = empty_output_buffer;
212  dest->pub.term_destination = term_destination_file_close;
213  dest->outfile = fopen(outfile,"wb");
214}
215
216
217
218/*
219API to close file in case of error. needed for win16. DLL that opens file must also close it.
220*/
221
222GLOBAL(void)
223jpeg_close_file(j_compress_ptr cinfo)
224{
225  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
226  fclose(dest->outfile);
227}
228
229
230
Note: See TracBrowser for help on using the repository browser.