Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
204 chris 1
/* JPEG To RGB interface --Raphael Grasset - 04/07/16 - 2004 Hitlab NZ. All Rights reserved--
2
 
3
This file define simple routine functions for  converting a JPEG image to RGB format.
4
It use is ONLY for EyeToy Camera.
5
 
6
WARNING : It use a static image area : at each call of conversion, the new
7
image is copying on the same memory area (limited dynamic allocation mamagement).
8
So be careful when you manipulating the pointer on the image !!
9
 
10
USAGE :
11
Based on libjpeg (providing hardware decompression), you need just add few things on your code:
12
 
13
#include "jpegtorgb.h" //this file
14
 
15
int xsiwe=640;//video image format
16
int ysize=480;//video image format
17
....
18
JPEGToRGBInit(xsize,ysize); //init function with image size in parameters
19
....
20
 
21
ARUint8* decompressed_image=JPEGToRGB(video_image,xsize,ysize); //converting function (converted image return)
22
 
23
don't be care with ARUint8, equivalent to an unsigned char format.
24
 
25
*/
26
 
27
#include "jpeglib.h"
28
#include "jerror.h"
29
#include <setjmp.h>
30
 
31
 
32
/*---------------- Direct Input Functions for libjpeg  --------------*/
33
 
34
/* we overload the interface for open a jpeg file : the libjpeg
35
file is limited for only FILE* input. Since we have a JPEG image
36
in memory we need a new interface for libjpeg. For these we overload
37
differents functions.
38
I have modified the code for jpeg_stdio_src, and providing
39
new functions name EyeToy_XXX (XXX template
40
 
41
Need to be optimized, cleaned.
42
*/
43
 
44
#define JFREAD(file,buf,sizeofbuf)  \
45
  ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
46
 
47
/* Expanded data source object for stdio input */
48
 
49
typedef struct {
50
  struct jpeg_source_mgr pub;   /* public fields */
51
 
52
  unsigned char* image;
53
  int image_size;
54
  JOCTET * buffer;              /* start of buffer */
55
  boolean start_of_file;        /* have we gotten any data yet? */
56
} my_source_mgr;
57
 
58
typedef my_source_mgr * my_src_ptr;
59
 
60
#define INPUT_BUF_SIZE  4096    /* choose an efficiently fread'able size */
61
 
62
/*
63
 * Initialize source --- called by jpeg_read_header
64
 * before any data is actually read.
65
 */
66
 
67
METHODDEF(void)
68
EyeToy_init_source (j_decompress_ptr cinfo)
69
{
70
  my_src_ptr src = (my_src_ptr) cinfo->src;
71
 
72
  /* We reset the empty-input-file flag for each image,
73
   * but we don't clear the input buffer.
74
   * This is correct behavior for reading a series of images from one source.
75
   */
76
  src->start_of_file = TRUE;
77
}
78
 
79
/*
80
 * Fill the input buffer --- called whenever buffer is emptied.
81
 *
82
 * In typical applications, this should read fresh data into the buffer
83
 * (ignoring the current state of next_input_byte & bytes_in_buffer),
84
 * reset the pointer & count to the start of the buffer, and return TRUE
85
 * indicating that the buffer has been reloaded.  It is not necessary to
86
 * fill the buffer entirely, only to obtain at least one more byte.
87
 *
88
 * There is no such thing as an EOF return.  If the end of the file has been
89
 * reached, the routine has a choice of ERREXIT() or inserting fake data into
90
 * the buffer.  In most cases, generating a warning message and inserting a
91
 * fake EOI marker is the best course of action --- this will allow the
92
 * decompressor to output however much of the image is there.  However,
93
 * the resulting error message is misleading if the real problem is an empty
94
 * input file, so we handle that case specially.
95
 *
96
 * In applications that need to be able to suspend compression due to input
97
 * not being available yet, a FALSE return indicates that no more data can be
98
 * obtained right now, but more may be forthcoming later.  In this situation,
99
 * the decompressor will return to its caller (with an indication of the
100
 * number of scanlines it has read, if any).  The application should resume
101
 * decompression after it has loaded more data into the input buffer.  Note
102
 * that there are substantial restrictions on the use of suspension --- see
103
 * the documentation.
104
 *
105
 * When suspending, the decompressor will back up to a convenient restart point
106
 * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
107
 * indicate where the restart point will be if the current call returns FALSE.
108
 * Data beyond this point must be rescanned after resumption, so move it to
109
 * the front of the buffer rather than discarding it.
110
 */
111
 
112
METHODDEF(boolean)
113
EyeToy_fill_input_buffer (j_decompress_ptr cinfo)
114
{
115
  my_src_ptr src = (my_src_ptr) cinfo->src;
116
 
117
  src->pub.next_input_byte = src->image;
118
  src->pub.bytes_in_buffer = src->image_size;
119
 
120
  src->start_of_file = FALSE;
121
 
122
  return TRUE;
123
}
124
 
125
/*
126
 * Skip data --- used to skip over a potentially large amount of
127
 * uninteresting data (such as an APPn marker).
128
 *
129
 * Writers of suspendable-input applications must note that skip_input_data
130
 * is not granted the right to give a suspension return.  If the skip extends
131
 * beyond the data currently in the buffer, the buffer can be marked empty so
132
 * that the next read will cause a fill_input_buffer call that can suspend.
133
 * Arranging for additional bytes to be discarded before reloading the input
134
 * buffer is the application writer's problem.
135
 */
136
 
137
METHODDEF(void)
138
EyeToy_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
139
{
140
  my_src_ptr src = (my_src_ptr) cinfo->src;
141
 
142
  /* Just a dumb implementation for now.  Could use fseek() except
143
   * it doesn't work on pipes.  Not clear that being smart is worth
144
   * any trouble anyway --- large skips are infrequent.
145
   */
146
  if (num_bytes > 0) {
147
    while (num_bytes > (long) src->pub.bytes_in_buffer) {
148
      num_bytes -= (long) src->pub.bytes_in_buffer;
149
      (void) EyeToy_fill_input_buffer(cinfo);
150
      /* note we assume that fill_input_buffer will never return FALSE,
151
       * so suspension need not be handled.
152
       */
153
    }
154
    src->pub.next_input_byte += (size_t) num_bytes;
155
    src->pub.bytes_in_buffer -= (size_t) num_bytes;
156
  }
157
}
158
 
159
/*
160
 * An additional method that can be provided by data source modules is the
161
 * resync_to_restart method for error recovery in the presence of RST markers.
162
 * For the moment, this source module just uses the default resync method
163
 * provided by the JPEG library.  That method assumes that no backtracking
164
 * is possible.
165
 */
166
 
167
/*
168
 * Terminate source --- called by jpeg_finish_decompress
169
 * after all data has been read.  Often a no-op.
170
 *
171
 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
172
 * application must deal with any cleanup that should happen even
173
 * for error exit.
174
 */
175
 
176
METHODDEF(void)
177
EyeToy_term_source (j_decompress_ptr cinfo)
178
{
179
  /* no work necessary here */
180
}
181
 
182
 
183
/*
184
The new jpeg access function : directly read the memory
185
buffer instead of a FILE* input. Since all the image
186
is in memory we put all the buffer in one pass.
187
*/
188
 
189
GLOBAL(void)
190
EyeToy_jpeg_stdio_src(j_decompress_ptr cinfo,unsigned char *image,int count)
191
{
192
  my_src_ptr src;
193
 
194
  /* The source object and input buffer are made permanent so that a series
195
   * of JPEG images can be read from the same file by calling jpeg_stdio_src
196
   * only before the first one.  (If we discarded the buffer at the end of
197
   * one image, we'd likely lose the start of the next one.)
198
   * This makes it unsafe to use this manager and a different source
199
   * manager serially with the same JPEG object.  Caveat programmer.
200
   */
201
  if (cinfo->src == NULL) {     /* first time for this JPEG object? */
202
    cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT,
203
    sizeof(my_source_mgr));
204
    src = (my_src_ptr) cinfo->src;
205
    src->buffer = (JOCTET *)
206
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof(JOCTET));
207
  }
208
 
209
  src = (my_src_ptr) cinfo->src;
210
  src->pub.init_source = EyeToy_init_source;
211
  src->pub.fill_input_buffer = EyeToy_fill_input_buffer;
212
  src->pub.skip_input_data = EyeToy_skip_input_data;
213
  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
214
  src->pub.term_source = EyeToy_term_source;
215
  src->image=image;
216
  src->image_size=count;
217
  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
218
  src->pub.next_input_byte = NULL; /* until buffer loaded */
219
}
220
 
221
static ARUint8* TransfertBufferImage;
222
 
223
/*---------------- Main Functions --------------*/
224
 
225
void JPEGToRGBInit(int xsize,int ysize)
226
{
227
  TransfertBufferImage = malloc(xsize*ysize*3);  
228
}
229
 
230
 
231
ARUint8* JPEGToRGB(ARUint8* image, int xsize,int ysize)
232
{
233
 
234
  int image_height=xsize;       /* Number of rows in image */
235
  int image_width=ysize;                /* Number of columns in image */
236
 
237
  struct jpeg_error_mgr jerr;
238
  struct jpeg_decompress_struct cinfo;
239
 
240
  JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */
241
  int row_stride;               /* physical row width in output buffer */
242
  int crows=0;
243
 
244
  cinfo.err = jpeg_std_error(&jerr);
245
 
246
  jpeg_create_decompress(&cinfo);
247
 
248
   ssize_t count;
249
   count=(image[0]+image[1]*65536)/8;
250
 
251
   EyeToy_jpeg_stdio_src(&cinfo,image+2,count);
252
 
253
  (void) jpeg_read_header(&cinfo, TRUE);
254
 
255
  (void) jpeg_start_decompress(&cinfo);
256
 
257
  row_stride = cinfo.output_width * cinfo.output_components;
258
  /* Make a one-row-high sample array that will go away when done with image */
259
 
260
  while (cinfo.output_scanline < cinfo.output_height)
261
  {
262
    row_pointer[0] = & TransfertBufferImage[crows * row_stride];
263
    (void) jpeg_read_scanlines(&cinfo, row_pointer, 1);    
264
    crows++;
265
  }
266
 
267
  (void) jpeg_finish_decompress(&cinfo);
268
 
269
  jpeg_destroy_decompress(&cinfo);
270
 
271
  return TransfertBufferImage;
272
}