source: golgotha/src/i4/loaders/jpg_write.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 5.6 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "image/image.hh"
10#include "file/file.hh"
11#include "status/status.hh"
12#include "loaders/jpg/jpeglib.h"
13
14
15boolean i4_jpg_empty(j_compress_ptr cinfo);
16void i4_jpg_null(j_compress_ptr cinfo) { }
17void i4_jpg_fin(j_compress_ptr cinfo);
18
19enum { JPG_BUF_SIZE=10*1024 };
20
21struct i4_jpg_write_mgr : public jpeg_destination_mgr
22{
23  w8 buf[JPG_BUF_SIZE];
24  int size;
25  i4_file_class *fp;
26
27  i4_jpg_write_mgr(i4_file_class *fp) : fp(fp)
28  {
29    init_destination=i4_jpg_null;
30    empty_output_buffer=i4_jpg_empty;
31    term_destination=i4_jpg_fin;
32
33    next_output_byte=(JOCTET *)buf;
34    free_in_buffer=JPG_BUF_SIZE;
35  }
36} *i4_current_jpg_write_mgr;
37
38boolean i4_jpg_empty(j_compress_ptr cinfo)
39{
40  i4_jpg_write_mgr *m=i4_current_jpg_write_mgr;
41
42  int ws=JPG_BUF_SIZE;
43  i4_current_jpg_write_mgr->fp->write(m->buf, ws);
44                                     
45  m->size+=ws;
46  m->next_output_byte=(JOCTET *)i4_current_jpg_write_mgr->buf;
47  m->free_in_buffer=JPG_BUF_SIZE;
48
49  return TRUE;
50}
51
52
53void i4_jpg_fin(j_compress_ptr cinfo)
54{
55  i4_jpg_write_mgr *m=i4_current_jpg_write_mgr;
56  int ws=(w8 *)m->next_output_byte-m->buf;
57  i4_current_jpg_write_mgr->fp->write(m->buf, ws);
58}
59
60// return size of jpeg written
61int i4_write_jpeg(i4_image_class *im,
62                    i4_file_class *fp,
63                    int quality,           // 0..100
64                    i4_status_class *status)
65{
66  if (im->width()>4096)
67    return 0;
68
69  /* This struct contains the JPEG compression parameters and pointers to
70   * working space (which is allocated as needed by the JPEG library).
71   * It is possible to have several such structures, representing multiple
72   * compression/decompression processes, in existence at once.  We refer
73   * to any one struct (and its associated working data) as a "JPEG object".
74   */
75  struct jpeg_compress_struct cinfo;
76  /* This struct represents a JPEG error handler.  It is declared separately
77   * because applications often want to supply a specialized error handler
78   * (see the second half of this file for an example).  But here we just
79   * take the easy way out and use the standard error handler, which will
80   * print a message on stderr and call exit() if compression fails.
81   * Note that this struct must live as long as the main JPEG parameter
82   * struct, to avoid dangling-pointer problems.
83   */
84  struct jpeg_error_mgr jerr;
85  /* More stuff */
86
87  /* Step 1: allocate and initialize JPEG compression object */
88
89  /* We have to set up the error handler first, in case the initialization
90   * step fails.  (Unlikely, but it could happen if you are out of memory.)
91   * This routine fills in the contents of struct jerr, and returns jerr's
92   * address which we place into the link field in cinfo.
93   */
94  cinfo.err = jpeg_std_error(&jerr);
95  /* Now we can initialize the JPEG compression object. */
96  jpeg_create_compress(&cinfo);
97
98  /* Step 2: specify data destination (eg, a file) */
99  /* Note: steps 2 and 3 can be done in either order. */
100
101 
102  i4_jpg_write_mgr write_mgr(fp);
103  i4_current_jpg_write_mgr=&write_mgr;
104
105  cinfo.dest = &write_mgr;
106
107
108  /* Step 3: set parameters for compression */
109  /* First we supply a description of the input image.
110   * Four fields of the cinfo struct must be filled in:
111   */
112  cinfo.image_width = im->width();      /* image width and height, in pixels */
113  cinfo.image_height = im->height();
114  cinfo.input_components = 3;           /* # of color components per pixel */
115  cinfo.in_color_space = JCS_RGB;       /* colorspace of input image */
116  /* Now use the library's routine to set default compression parameters.
117   * (You must set at least cinfo.in_color_space before calling this,
118   * since the defaults depend on the source color space.)
119   */
120  jpeg_set_defaults(&cinfo);
121  /* Now you can set any non-default parameters you wish to.
122   * Here we just illustrate the use of quality (quantization table) scaling:
123   */
124  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
125
126  /* Step 4: Start compressor */
127
128  /* TRUE ensures that we will write a complete interchange-JPEG file.
129   * Pass TRUE unless you are very sure of what you're doing.
130   */
131  jpeg_start_compress(&cinfo, TRUE);
132
133  /* Step 5: while (scan lines remain to be written) */
134  /*           jpeg_write_scanlines(...); */
135
136
137  w8 buf[4096*3];
138 
139  int im_w=im->width();
140
141  while (cinfo.next_scanline < cinfo.image_height)
142  {
143    if (status)
144      status->update((float)cinfo.next_scanline/cinfo.image_height);
145
146    JSAMPROW scanline[1]={buf};
147    w8 *c=buf;
148       
149    for (int x=0; x<im_w; x++)
150    {
151      i4_color color=im->get_pixel(x, cinfo.next_scanline);
152      c[0]=(color>>16)&0xff;
153      c[1]=(color>>8)&0xff;
154      c[2]=(color)&0xff;
155      c+=3;
156    }
157    jpeg_write_scanlines(&cinfo, scanline, 1);
158  }
159
160  /* Step 6: Finish compression */
161
162  jpeg_finish_compress(&cinfo);
163
164  /* Step 7: release JPEG compression object */
165
166  /* This is an important step since it will release a good deal of memory. */
167  jpeg_destroy_compress(&cinfo);
168
169
170  return write_mgr.size;
171  /* And we're done! */
172}
Note: See TracBrowser for help on using the repository browser.