1#ifndef SIMAGE_H
2#define SIMAGE_H
3
4/*
5 * simage:
6 *
7 * A simple library for loading images. This library is designed
8 * for loading textures to be used as OpenGL textures.
9 * Only pixel formats directly supported by OpenGL (v1.0) will be
10 * returned. The user is responsible for resizing the texture to
11 * a 2^n width/height though.
12 *
13 * This library does not support the "new" OpenGL v1.1 image
14 * formats. In the future this might be supported though. We still
15 * have some old SGI HW with only OpenGL v1.0 installed...
16 *
17 * Usage information:
18 *
19 * simage_check_supported(filename):
20 *
21 *   Will return 1 if filename can be loaded, 0 otherwise.
22 *
23 * simage_read_image(filename, width, height, numComponents)
24 *
25 *   Will (attempt to) read filename, and return a pointer to
26 *   the image data. NULL is returned if the image could not
27 *   be loaded. The memory is allocated using malloc(), and
28 *   it is the callers responsibility to free the memory (using free())
29 *   width and height contains the width and height of the image,
30 *   and numComponents is a number indicating the following:
31 *     1 : Grayscale image (GL_LUMINANCE)
32 *     2 : Grayscale with alpha channel (GL_LUMINANCE_ALPHA)
33 *     3 : RGB data (GL_RGB)
34 *     4 : RGB data with alpha component (GL_RGBA)
35 *
36 * int simage_check_save_supported(const char * filenameextension)
37 *
38 *   Returns 1 if a saver of type filenameextension is added. The
39 *   built-in savers are gif, jpg/jpeg, png, tif/tiff and rgb.
40 *
41 * int simage_save_image(const char * filename,
42 *                       const unsigned char * bytes,
43 *                       int w, int h, int numcomponents,
44 *                       const char * filenameextension)
45 *
46 *   Saves image in the format specified in filenameextension.
47 *
48 * A couple of functions for your convenience:
49 *
50 * simage_resize(imagedata, width, height, numComponents,
51 *               newwidth, newheight)
52 *
53 *   A convenience function that can be used to resize an image.
54 *   Since OpenGL textures must have width and height equal to 2^n,
55 *   this is often needed. A pointer to the new image data is returned.
56 *   imagedata is not freed. Uses the algorithm "Filtered Image
57 *   Rescaling" by Dale Schumacher, from GGems III.
58 *
59 * simage_next_power_of_two(int val)
60 *
61 *   Will return the first 2^n bigger or equal to val.
62 *   If simage_next_power_of_two(size) != size, you'll typically
63 *   need to resize your image to be able to use it in an OpenGL app.
64 *
65 * The movie functions:
66 *
67 * s_movie * s_movie_create(const char * filename, s_params * params)
68 *
69 *   Will create a new move file named filename and attempt to locate a
70 *   suitable encoder based on the parameters (params) supplied.
71 *
72 *   Returns a pointer to the opened movie on success, NULL on failure
73 *
74 *   Common parameters:
75 *   - "mime-type" <string> : The requested encoder type. There are currently
76 *     2 encoders available, with mime-types "video/mpeg" and "video/avi".
77 *   - width <int> : Frame width (all input images must have this width)
78 *   - height <int> : Frame height (all input images must have this height)
79 *
80 *   Parameters specific for the avi encoder
81 *   - fps <int> : Number of frames per second in output file
82 *   - parameter file <int> : If this parameter is missing (or empty ""),
83 *     a GUI will pop up each time this functions is run, asking the user
84 *     to specify compression settings. If a filename is specified and the
85 *     file doesn't exist, a GUI pops up, and the compression settings are
86 *     saved in a new file with the specified filename. If the file exists,
87 *     no GUI pops up, and the compression settings are read from the file.
88 *     The format of the file is unspecified, and copying such a file between
89 *     different computers probably won't work.
90 *   - width and height must be divisible by 4
91 *
92 * int s_movie_put_image(s_movie * movie, s_image * image, s_params * params)
93 *
94 *   Adds (encodes) the image as one frame to the movie. params is currently
95 *   used only for optimizing avi encoding:
96 *   - "allow image modification" <int> : Set to "1" to allow the encoder
97 *     to modify the image buffer. If this parameter is not set, the encoder
98 *     will make a local copy of the image before it is encoded.
99 *
100 *   Example code:
101 *
102 *   s_params *imgparams = s_params_create();
103 *   s_params_set(imgparams,
104 *                "allow image modification", S_INTEGER_PARAM_TYPE, 1,
105 *                NULL);
106 *   for(;;) {
107 *     s_image_set(image, width, height, 1, <get image from somewhere>);
108 *     for (int i=0; i<repeatCount;i++)
109 *       s_movie_put_image(movie, image, imgparams);
110 *   }
111 *   s_params_destroy(imgparams);
112 *
113 *   Returns 1 on success, 0 on failure
114 *
115 * void s_movie_close(s_movie * movie)
116 *
117 *   Closes the newly created movie file
118 *
119 * void s_movie_destroy(s_movie * movie)
120 *
121 *   Cleans up all resources allocated by s_movie_create(...)
122 *
123 */
124
125/***************************************************************************/
126
127/* A unique identifier to recognize in sourcecode whether or not this
128 * file is included.
129 */
130#define __SIMAGE__
131
132/* version 1.1 introduced saving */
133#define SIMAGE_VERSION_1_1
134
135/* version 1.2 added a new API, and support for movies */
136#define SIMAGE_VERSION_1_2
137
138/* version 1.3 added simage_resize3d */
139#define SIMAGE_VERSION_1_3
140
141/* version 1.4 added API for stream I/O */
142#define SIMAGE_VERSION_1_4
143
144/* version 1.5 added API for seeking and getting ("telling") the
145               current position in a stream
146               added API for setting and getting component order of an
147               image */
148#define SIMAGE_VERSION_1_5
149
150/* version 1.6 added API for reading images line-by-line
151               added API for loading dynamic libraries at run-time */
152#define SIMAGE_VERSION_1_6
153
154/* These are available for adding or omitting features based on simage
155 * version numbers in "client" sources. NB: they are automatically
156 * synchronized with the settings in configure.in when configure is
157 * run. The #ifndefs are necessary because during development, these
158 * are also defined in the config.h file generated by configure.
159 */
160#if !defined(SIMAGE_MAJOR_VERSION)
161#undef SIMAGE_MAJOR_VERSION
162#endif /* !SIMAGE_MAJOR_VERSION */
163#if !defined(SIMAGE_MINOR_VERSION)
164#undef SIMAGE_MINOR_VERSION
165#endif /* !SIMAGE_MINOR_VERSION */
166#if !defined(SIMAGE_MICRO_VERSION)
167#undef SIMAGE_MICRO_VERSION
168#endif /* !SIMAGE_MICRO_VERSION */
169#if !defined(SIMAGE_VERSION)
170#undef SIMAGE_VERSION
171#endif /* !SIMAGE_VERSION */
172
173/***************************************************************************/
174
175/* Precaution to avoid an error easily made by the application programmer. */
176#ifdef SIMAGE_DLL_API
177# error Leave the internal SIMAGE_DLL_API define alone.
178#endif /* SIMAGE_DLL_API */
179
180/*
181  On MSWindows platforms, one of these defines must always be set when
182  building application programs:
183
184   - "SIMAGE_DLL", when the application programmer is using the
185     library in the form of a dynamic link library (DLL)
186
187   - "SIMAGE_NOT_DLL", when the application programmer is using the
188     library in the form of a static object library (LIB)
189
190  Note that either SIMAGE_DLL or SIMAGE_NOT_DLL _must_ be defined by
191  the application programmer on MSWindows platforms, or else the
192  #error statement will hit. Set up one or the other of these two
193  defines in your compiler environment according to how the library
194  was built -- as a DLL (use "SIMAGE_DLL") or as a LIB (use
195  "SIMAGE_NOT_DLL").
196
197  (Setting up defines for the compiler is typically done by either
198  adding something like "/DSIMAGE_DLL" to the compiler's argument line
199  (for command-line build processes), or by adding the define to the
200  list of preprocessor symbols in your IDE GUI (in the MSVC IDE, this
201  is done from the "Project"->"Settings" menu, choose the "C/C++" tab,
202  then "Preprocessor" from the dropdown box and add the appropriate
203  define)).
204
205  It is extremely important that the application programmer uses the
206  correct define, as using "SIMAGE_NOT_DLL" when "SIMAGE_DLL" is
207  correct will cause mysterious crashes.
208 */
209#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
210# ifdef SIMAGE_INTERNAL
211#  ifdef SIMAGE_MAKE_DLL
212#   define SIMAGE_DLL_API __declspec(dllexport)
213#  endif /* SIMAGE_MAKE_DLL */
214# else /* !SIMAGE_INTERNAL */
215#  ifdef SIMAGE_DLL
216#   define SIMAGE_DLL_API __declspec(dllimport)
217#  else /* !SIMAGE_DLL */
218#   ifndef SIMAGE_NOT_DLL
219#    error Define either SIMAGE_DLL or SIMAGE_NOT_DLL as appropriate for your linkage!
220#   endif /* SIMAGE_NOT_DLL */
221#  endif /* !SIMAGE_DLL */
222# endif /* !SIMAGE_INTERNAL */
223#endif /* Microsoft Windows */
224
225/* Empty define to avoid errors when _not_ compiling an MSWindows DLL. */
226#ifndef SIMAGE_DLL_API
227# define SIMAGE_DLL_API
228#endif /* !SIMAGE_DLL_API */
229
230/***************************************************************************/
231
232#ifdef __cplusplus
233extern "C" {
234#endif
235
236  /* Note specifically for MSWindows that by leaving out the APIENTRY
237     keyword for the function definitions, we default to the __cdecl
238     calling convention. This is important to take into consideration
239     when explicitly linking to the library at run-time: when using
240     the wrong calling convention, obscure errors due to stack
241     corruption can occur under certain (possibly rare) conditions. */
242
243  /* run-time version checking */
244  SIMAGE_DLL_API void simage_version(int * major, int * minor, int * micro);
245
246  /* check if image file format is supported */
247  SIMAGE_DLL_API int simage_check_supported(const char * filename);
248
249  /* reading and parsing image files */
250  /* returned image buffer must be freed by simage_free_image() */
251  SIMAGE_DLL_API unsigned char * simage_read_image(const char * filename,
252                                                   int * w, int * h,
253                                                   int * numcomponents);
254
255  /* check this if simage_read_image returns NULL or simage_write_image returns 0 */
256  SIMAGE_DLL_API const char * simage_get_last_error(void);
257
258  /* free resources allocated by either simage_read_image() or
259     simage_resize() (Windows goes berzerk if you call free() from the
260     client application) */
261  SIMAGE_DLL_API void simage_free_image(unsigned char * imagedata);
262
263  /* convenience function */
264  SIMAGE_DLL_API int simage_next_power_of_two(int val);
265
266  /* scale the input image and return a new image with the given dimensions */
267  /* returned image buffer must be freed by simage_free_image() */
268  SIMAGE_DLL_API unsigned char * simage_resize(unsigned char * imagedata,
269                                               int width, int height,
270                                               int numcomponents,
271                                               int newwidth, int newheight);
272
273  /* use the plugin interface described below for extending simage to
274     handle more file formats */
275
276  struct simage_plugin
277  {
278    unsigned char *(*load_func)(const char * name, int * width, int * height,
279                                int * numcomponents);
280    int (*identify_func)(const char * filename,
281                         const unsigned char * header, int headerlen);
282    int (*error_func)(char * textbuffer, int bufferlen);
283  };
284
285  SIMAGE_DLL_API void * simage_add_loader(const struct simage_plugin * l,
286                                          int addbefore);
287  SIMAGE_DLL_API void simage_remove_loader(void * handle);
288
289
290  /*****************************************************************/
291  /**** NOTE: new methods for simage version 1.1 *******************/
292  /*****************************************************************/
293
294  /* check if export is available for a filetype. Returns 1 if supported, 0 otherwise */
295  SIMAGE_DLL_API int simage_check_save_supported(const char * filenameextension);
296
297  /* save image. use simage_check_write_supported first, please */
298  SIMAGE_DLL_API int simage_save_image(const char * filename,
299                                       const unsigned char * bytes,
300                                       int w, int h, int numcomponents,
301                                       const char * filenameextension);
302
303  SIMAGE_DLL_API void * simage_add_saver(int (*save_func)(const char * name,
304                                                          const unsigned char * bytes,
305                                                          int width, int height, int nc),
306                                         int (*error_func)(char * textbuffer, int bufferlen),
307                                         const char * extensions,
308                                         const char * fullname,
309                                         const char * description,
310                                         int addbefore);
311
312  SIMAGE_DLL_API void simage_remove_saver(void * handle);
313  SIMAGE_DLL_API int simage_get_num_savers(void);
314  SIMAGE_DLL_API void * simage_get_saver_handle(int idx);
315  SIMAGE_DLL_API const char * simage_get_saver_extensions(void * handle);
316  SIMAGE_DLL_API const char * simage_get_saver_fullname(void * handle);
317  SIMAGE_DLL_API const char * simage_get_saver_description(void * handle);
318
319
320  /*****************************************************************/
321  /**** NOTE: new methods for simage version 1.2 *******************/
322  /*****************************************************************/
323
324  typedef struct simage_image_s s_image;
325  typedef struct simage_movie_s s_movie;
326  typedef struct simage_parameters_s s_params;
327  typedef int s_movie_open_func(const char *, s_movie *);
328  typedef int s_movie_create_func(const char *, s_movie *, s_params *);
329  typedef s_image * s_movie_get_func(s_movie *, s_image *, s_params *);
330  typedef int s_movie_put_func(s_movie *, s_image *, s_params *);
331  typedef void s_movie_close_func(s_movie *);
332
333  SIMAGE_DLL_API s_image * s_image_create(int w, int h, int components,
334                                          unsigned char * prealloc /* | NULL */);
335  SIMAGE_DLL_API void s_image_destroy(s_image * image);
336
337  SIMAGE_DLL_API int s_image_width(s_image * image);
338  SIMAGE_DLL_API int s_image_height(s_image * image);
339  SIMAGE_DLL_API int s_image_components(s_image * image);
340  SIMAGE_DLL_API unsigned char * s_image_data(s_image * image);
341  SIMAGE_DLL_API void s_image_set(s_image * image, int w, int h, int components,
342                                  unsigned char * data, int copydata);
343
344  SIMAGE_DLL_API s_image * s_image_load(const char * filename, s_image * prealloc /* | NULL */);
345  SIMAGE_DLL_API int s_image_save(const char * filename, s_image * image,
346                                  s_params * params /* | NULL */);
347
348  SIMAGE_DLL_API s_movie * s_movie_open(const char * filename);
349  SIMAGE_DLL_API s_movie * s_movie_create(const char * filename, s_params * params /* | NULL */);
350  SIMAGE_DLL_API s_image * s_movie_get_image(s_movie * movie, s_image * prealloc /* | NULL */,
351                                             s_params * params /* | NULL */);
352  SIMAGE_DLL_API int s_movie_put_image(s_movie * movie, s_image * image,
353                                       s_params * params /* | NULL */);
354  SIMAGE_DLL_API void s_movie_close(s_movie * movie);
355  SIMAGE_DLL_API void s_movie_destroy(s_movie * movie);
356
357  SIMAGE_DLL_API void s_movie_importer_add(s_movie_open_func * open,
358                                           s_movie_get_func * get,
359                                           s_movie_close_func * close);
360
361  SIMAGE_DLL_API void s_movie_exporter_add(s_movie_create_func * create,
362                                           s_movie_put_func * put,
363                                           s_movie_close_func * close);
364
365  enum {
366    S_INTEGER_PARAM_TYPE,
367    S_BOOL_PARAM_TYPE = S_INTEGER_PARAM_TYPE,
368    S_FLOAT_PARAM_TYPE,
369    S_DOUBLE_PARAM_TYPE,
370    S_STRING_PARAM_TYPE,
371    S_POINTER_PARAM_TYPE,
372    S_FUNCTION_PARAM_TYPE
373  };
374
375  SIMAGE_DLL_API s_params * s_params_create(void);
376  SIMAGE_DLL_API s_params * s_params_copy(s_params * params);
377  SIMAGE_DLL_API void s_params_destroy(s_params * params);
378
379  SIMAGE_DLL_API void s_params_set(s_params * params, ...);
380  SIMAGE_DLL_API int s_params_get(s_params * params, ...);
381
382  /*****************************************************************/
383  /**** NOTE: new methods for simage version 1.3 *******************/
384  /*****************************************************************/
385
386  /* returned image buffer must be freed by simage_free_image() */
387  SIMAGE_DLL_API unsigned char * simage_resize3d(unsigned char * imagedata,
388                                                 int width, int height,
389                                                 int numcomponents,
390                                                 int layers,
391                                                 int newwidth, int newheight,
392                                                 int newlayers);
393
394  /*****************************************************************/
395  /**** NOTE: new methods for simage version 1.4 *******************/
396  /*****************************************************************/
397
398  typedef struct simage_stream_s s_stream;
399  typedef int s_stream_open_func(const char *, s_stream *, s_params *);
400  typedef int s_stream_create_func(const char *, s_stream *, s_params *);
401  typedef void * s_stream_get_func(s_stream *, void *, int *, s_params *);
402  typedef int s_stream_put_func(s_stream *, void *, int, s_params *);
403  typedef void s_stream_close_func(s_stream *);
404
405  SIMAGE_DLL_API s_stream * s_stream_open(const char * filename,
406                                          s_params * params /* | NULL */);
407  SIMAGE_DLL_API s_stream * s_stream_create(const char * filename,
408                                            s_params * params /* | NULL */);
409  SIMAGE_DLL_API void * s_stream_get_buffer(s_stream * stream,
410                                            void * prealloc /* | NULL */,
411                                            int *size /* | NULL */,
412                                            s_params * params /* | NULL */);
413  SIMAGE_DLL_API int s_stream_put_buffer(s_stream * stream, void * buffer,
414                                         int size,
415                                         s_params * params /* | NULL */);
416  SIMAGE_DLL_API void s_stream_close(s_stream * stream);
417  SIMAGE_DLL_API void s_stream_destroy(s_stream * stream);
418  SIMAGE_DLL_API s_params * s_stream_params(s_stream * stream);
419
420  SIMAGE_DLL_API void s_stream_importer_add(s_stream_open_func * open,
421                                            s_stream_get_func * get,
422                                            s_stream_close_func * close);
423
424  SIMAGE_DLL_API void s_stream_exporter_add(s_stream_create_func * create,
425                                            s_stream_put_func * put,
426                                            s_stream_close_func * close);
427
428  /*****************************************************************/
429  /**** NOTE: new methods for simage version 1.5 *******************/
430  /*****************************************************************/
431
432  typedef int s_stream_seek_func(s_stream *, int, int, s_params *);
433  typedef int s_stream_tell_func(s_stream *, s_params *);
434
435  enum {
436    SIMAGE_SEEK_SET = 0,
437    SIMAGE_SEEK_CUR = 1,
438    SIMAGE_SEEK_END = 2
439  };
440
441
442  SIMAGE_DLL_API int s_stream_seek(s_stream * stream, int offset, int whence,
443                                   s_params * params /* | NULL */);
444  SIMAGE_DLL_API int s_stream_tell(s_stream *stream,
445                                   s_params * params /* | NULL */);
446
447  SIMAGE_DLL_API void s_stream_importer_add_ex(s_stream_open_func * open,
448                                               s_stream_get_func * get,
449                                               s_stream_seek_func * seek,
450                                               s_stream_tell_func * tell,
451                                               s_stream_close_func * close);
452
453  SIMAGE_DLL_API void s_stream_exporter_add_ex(s_stream_create_func * create,
454                                               s_stream_put_func * put,
455                                               s_stream_seek_func * seek,
456                                               s_stream_tell_func * tell,
457                                               s_stream_close_func * close);
458
459  enum {
460    SIMAGE_ORDER_RGB = 0,
461    SIMAGE_ORDER_BGR
462  };
463  SIMAGE_DLL_API int s_image_set_component_order(s_image * image, int order);
464  SIMAGE_DLL_API int s_image_get_component_order(s_image * image);
465
466  /*****************************************************************/
467  /**** NOTE: new methods for simage version 1.6 *******************/
468  /*****************************************************************/
469
470  SIMAGE_DLL_API s_image * s_image_open(const char * file, int oktoreadall);
471  SIMAGE_DLL_API int s_image_read_line(s_image * image,
472                                       int line,
473                                       unsigned char * buf);
474
475  typedef void * s_dlopen_func(const char * filename);
476  typedef void * s_dlsym_func(void * handle, const char * symbolname);
477  typedef void s_dlclose_func(void * handle);
478
479  SIMAGE_DLL_API void s_set_dynamic_loader_interface(s_dlopen_func *dlopen,
480                                                     s_dlsym_func *dlsym,
481                                                     s_dlclose_func *dlclose);
482
483
484
485#ifdef __cplusplus
486}
487#endif
488
489#endif /* ! SIMAGE_H */
490