1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif /* HAVE_CONFIG_H */
8 #include <simage.h>
9 #include <simage_private.h>
10 #include <string.h>
11 
12 s_image *
s_image_create(int w,int h,int components,unsigned char * prealloc)13 s_image_create(int w, int h, int components,
14                unsigned char * prealloc /* | NULL */ )
15 {
16   s_image * image = (s_image*) malloc(sizeof(s_image));
17   image->width = w;
18   image->height = h;
19   image->components = components;
20   image->order = SIMAGE_ORDER_RGB;
21   image->didalloc = 0;
22   image->data = prealloc;
23   if (image->data == NULL) {
24     image->didalloc = 1;
25     image->data = (unsigned char *) malloc(w*h*components);
26   }
27 
28   /* needed for simage 1.6 */
29   image->opendata = NULL;
30   image->oktoreadall = 1;
31   image->openfilename = NULL;
32   memset(&image->openfuncs, 0, sizeof(struct simage_open_funcs));
33 
34   /* return image struct */
35   return (s_image*) image;
36 }
37 
38 void
s_image_destroy(s_image * image)39 s_image_destroy(s_image * image)
40 {
41   if (image) {
42     if (image->didalloc) free((void*)image->data);
43 
44     if (image->opendata) {
45       image->openfuncs.close_func(image->opendata);
46     }
47     if (image->openfilename) {
48       free((void*) image->openfilename);
49     }
50     free((void*)image);
51   }
52 }
53 
54 int
s_image_width(s_image * image)55 s_image_width(s_image * image)
56 {
57   if (image) return image->width;
58   return 0;
59 }
60 
61 int
s_image_height(s_image * image)62 s_image_height(s_image * image)
63 {
64   if (image) return image->height;
65   return 0;
66 }
67 
68 int
s_image_components(s_image * image)69 s_image_components(s_image * image)
70 {
71   if (image) return image->components;
72   return 0;
73 }
74 
75 
76 int
s_image_set_component_order(s_image * image,int order)77 s_image_set_component_order(s_image * image, int order)
78 {
79   int oldorder = image->order;
80   image->order = order;
81   return oldorder;
82 }
83 
84 int
s_image_get_component_order(s_image * image)85 s_image_get_component_order(s_image * image)
86 {
87   return image->order;
88 }
89 
90 unsigned char *
s_image_data(s_image * image)91 s_image_data(s_image * image)
92 {
93   if (image) {
94     if (image->opendata && image->data == NULL) {
95       int i;
96       image->data = (unsigned char *) malloc(image->width*image->height*image->components);
97       image->didalloc = 1;
98       for (i = 0; i < image->height; i++) {
99         (void) s_image_read_line(image, i,
100                                  image->data+image->width*image->components);
101       }
102     }
103     return image->data;
104   }
105   return NULL;
106 }
107 
108 void
s_image_set(s_image * image,int w,int h,int components,unsigned char * data,int copydata)109 s_image_set(s_image * image, int w, int h, int components,
110             unsigned char * data, int copydata)
111 {
112   if (image->width == w && image->height == h && image->components == components) {
113     if (copydata) {
114       if (!image->didalloc) {
115         /* we shouldn't overwrite preallocated data */
116         image->data = (unsigned char*) malloc(w*h*components);
117         image->didalloc = 1;
118       }
119       memcpy(image->data, data, w*h*components);
120     }
121     else {
122       if (image->didalloc) free((void*) image->data);
123       image->data = data;
124       image->didalloc = 0;
125     }
126   }
127   else {
128     if (image->didalloc) free((void*) image->data);
129     image->width = w;
130     image->height = h;
131     image->components = components;
132     if (copydata) {
133       image->data = (unsigned char *) malloc(w*h*components);
134       image->didalloc = 1;
135       memcpy(image->data, data, w*h*components);
136     }
137     else {
138       image->data = data;
139       image->didalloc = 0;
140     }
141   }
142   image->order = SIMAGE_ORDER_RGB;
143 }
144 
145 s_image *
s_image_load(const char * filename,s_image * prealloc)146 s_image_load(const char * filename, s_image * prealloc /* | NULL */)
147 {
148   unsigned char * data;
149   int w,h,nc;
150 
151   data = simage_read_image(filename, &w, &h, &nc);
152   if (data == NULL) return NULL;
153   if (prealloc == NULL ||
154       prealloc->width != w ||
155       prealloc->height != h ||
156       prealloc->components != nc) {
157     prealloc = s_image_create(w, h, nc, data);
158     prealloc->didalloc = 1; /* we did alloc this data */
159   }
160   else {
161     /* copy into preallocated buffer */
162     memcpy(prealloc->data, data, w*h*nc);
163 
164     /* we don't need this copy any more */
165     simage_free_image(data);
166   }
167   prealloc->order = SIMAGE_ORDER_RGB;
168   prealloc->openfilename = (char*) malloc(strlen(filename) + 1);
169   strcpy(prealloc->openfilename, filename);
170   return prealloc;
171 }
172 
173 int
s_image_save(const char * filename,s_image * image,s_params * params)174 s_image_save(const char * filename, s_image * image,
175              s_params * params /* | NULL */)
176 {
177   char * ext = NULL;
178   if (params != NULL) {
179     s_params_get(params, S_STRING_PARAM_TYPE,
180                  "file type", &ext,
181                  NULL);
182   }
183   if (ext == NULL) {
184     ext = (char*) strrchr(filename, '.');
185     if (ext == NULL) return 0;
186 
187     /* skip period */
188     ext++;
189   }
190 
191   return simage_save_image(filename,
192                            s_image_data(image),
193                            image->width,
194                            image->height,
195                            image->components,
196                            ext);
197 }
198