]> Creatis software - gdcm.git/blob - src/jdatadst.cxx
Fix mistypings
[gdcm.git] / src / jdatadst.cxx
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
19
20 /* Expanded data destination object for stdio output */
21
22 extern "C" {
23   typedef  boolean(*boolean_jpeg_compress_struct)(jpeg_compress_struct*);
24   typedef  void(*void_jpeg_compress_struct)(jpeg_compress_struct*);
25 }
26
27 typedef struct {
28   struct jpeg_destination_mgr pub; /* public fields */
29
30   std::ostream * outfile; /* target stream */ 
31   JOCTET * buffer;         /* start of buffer */
32 //  boolean start_of_file;  /* have we gotten any data yet? */
33
34   size_t frag_length;  //we have to control this one to spec the size of the frag
35   size_t bytes_written;
36 } my_destination_mgr;
37
38 typedef my_destination_mgr * my_dest_ptr;
39
40 #define OUTPUT_BUF_SIZE  4096  /* choose an efficiently fwrite'able size */
41
42
43 /*
44  * Initialize destination --- called by jpeg_start_compress
45  * before any data is actually written.
46  */
47
48 METHODDEF(void)
49 init_destination (j_compress_ptr cinfo)
50 {
51   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
52
53   /* Allocate the output buffer --- it will be released when done with image */
54   dest->buffer = (JOCTET *)
55       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
56           OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
57
58   dest->pub.next_output_byte = dest->buffer;
59   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
60 }
61
62
63 /*
64  * Empty the output buffer --- called whenever buffer fills up.
65  *
66  * In typical applications, this should write the entire output buffer
67  * (ignoring the current state of next_output_byte & free_in_buffer),
68  * reset the pointer & count to the start of the buffer, and return TRUE
69  * indicating that the buffer has been dumped.
70  *
71  * In applications that need to be able to suspend compression due to output
72  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
73  * In this situation, the compressor will return to its caller (possibly with
74  * an indication that it has not accepted all the supplied scanlines).  The
75  * application should resume compression after it has made more room in the
76  * output buffer.  Note that there are substantial restrictions on the use of
77  * suspension --- see the documentation.
78  *
79  * When suspending, the compressor will back up to a convenient restart point
80  * (typically the start of the current MCU). next_output_byte & free_in_buffer
81  * indicate where the restart point will be if the current call returns FALSE.
82  * Data beyond this point will be regenerated after resumption, so do not
83  * write it out when emptying the buffer externally.
84  */
85
86 METHODDEF(boolean)
87 empty_output_buffer (j_compress_ptr cinfo)
88 {
89   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
90
91   if( dest->bytes_written == dest->frag_length )
92     {
93     // Start the I/O suspension simply by returning false here:
94     return FALSE;
95     }
96
97   size_t output_buf_size = OUTPUT_BUF_SIZE;
98   if( (dest->bytes_written + OUTPUT_BUF_SIZE) > dest->frag_length )
99     {
100     output_buf_size = dest->frag_length - dest->bytes_written;
101     }
102   dest->outfile->write((char*)dest->buffer, output_buf_size);
103   size_t nbytes = output_buf_size; //dest->outfile->gcount();
104
105   if( nbytes <= 0 )
106     ERREXIT(cinfo, JERR_FILE_WRITE);
107
108   if( dest->outfile->fail() )
109     ERREXIT(cinfo, JERR_FILE_WRITE);
110
111   dest->pub.next_output_byte = dest->buffer;
112   dest->pub.free_in_buffer = nbytes; //OUTPUT_BUF_SIZE;
113   dest->bytes_written += nbytes;
114
115   return TRUE;
116 }
117
118
119 /*
120  * Terminate destination --- called by jpeg_finish_compress
121  * after all data has been written.  Usually needs to flush buffer.
122  *
123  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
124  * application must deal with any cleanup that should happen even
125  * for error exit.
126  */
127
128 METHODDEF(void)
129 term_destination (j_compress_ptr cinfo)
130 {
131   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
132   size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
133
134   /* Write any data remaining in the buffer */
135 #if 0
136   if (datacount > 0) {
137     if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
138       ERREXIT(cinfo, JERR_FILE_WRITE);
139   }
140   fflush(dest->outfile);
141   /* Make sure we wrote the output file OK */
142   if (ferror(dest->outfile))
143     ERREXIT(cinfo, JERR_FILE_WRITE);
144 #else
145   if (datacount > 0) {
146     dest->outfile->write((char*)dest->buffer, datacount);
147     if (dest->outfile->fail())
148       ERREXIT(cinfo, JERR_FILE_WRITE);
149     dest->outfile->flush();
150     /* Make sure we wrote the output file OK */
151     if (dest->outfile->fail())
152       ERREXIT(cinfo, JERR_FILE_WRITE);
153   }
154 #endif
155 }
156
157
158 /*
159  * Prepare for output to a stdio stream.
160  * The caller must have already opened the stream, and is responsible
161  * for closing it after finishing compression.
162  */
163
164 GLOBAL(void)
165 jpeg_stdio_dest (j_compress_ptr cinfo, std::ostream * outfile, size_t frag_length, int flag)
166 {
167   my_dest_ptr dest;
168
169   /* The destination object is made permanent so that multiple JPEG images
170    * can be written to the same file without re-executing jpeg_stdio_dest.
171    * This makes it dangerous to use this manager and a different destination
172    * manager serially with the same JPEG object, because their private object
173    * sizes may be different.  Caveat programmer.
174    */
175   if (cinfo->dest == NULL) {  /* first time for this JPEG object? */
176     cinfo->dest = (struct jpeg_destination_mgr *)
177       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
178           SIZEOF(my_destination_mgr));
179   }
180
181   dest = (my_dest_ptr) cinfo->dest;
182   dest->pub.init_destination = reinterpret_cast<void_jpeg_compress_struct>(init_destination);
183   dest->pub.empty_output_buffer = reinterpret_cast<boolean_jpeg_compress_struct>(empty_output_buffer);
184   dest->pub.term_destination = reinterpret_cast<void_jpeg_compress_struct>(term_destination);
185   dest->outfile = outfile;
186
187   // Need to setup a new buffer, clean bytes_in_buffer and next_input_byte
188   if( flag )
189     {
190     dest->bytes_written = 0;
191     }
192   // only upate the new fragment, valid for both 'flag' value
193   dest->frag_length = frag_length;
194 }