add BLI_strcpy_rlen, replace strcat, which was used in misleading way.
[blender.git] / intern / cycles / render / image.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "device.h"
20 #include "image.h"
21 #include "scene.h"
22
23 #include "util_foreach.h"
24 #include "util_image.h"
25 #include "util_path.h"
26 #include "util_progress.h"
27
28 #ifdef WITH_OSL
29 #include <OSL/oslexec.h>
30 #endif
31
32 CCL_NAMESPACE_BEGIN
33
34 ImageManager::ImageManager()
35 {
36         need_update = true;
37         pack_images = false;
38         osl_texture_system = NULL;
39         animation_frame = 0;
40
41         tex_num_images = TEX_NUM_IMAGES;
42         tex_num_float_images = TEX_NUM_FLOAT_IMAGES;
43         tex_image_byte_start = TEX_IMAGE_BYTE_START;
44 }
45
46 ImageManager::~ImageManager()
47 {
48         for(size_t slot = 0; slot < images.size(); slot++)
49                 assert(!images[slot]);
50         for(size_t slot = 0; slot < float_images.size(); slot++)
51                 assert(!float_images[slot]);
52 }
53
54 void ImageManager::set_pack_images(bool pack_images_)
55 {
56         pack_images = pack_images_;
57 }
58
59 void ImageManager::set_osl_texture_system(void *texture_system)
60 {
61         osl_texture_system = texture_system;
62 }
63
64 void ImageManager::set_extended_image_limits(void)
65 {
66         tex_num_images = TEX_EXTENDED_NUM_IMAGES;
67         tex_num_float_images = TEX_EXTENDED_NUM_FLOAT_IMAGES;
68         tex_image_byte_start = TEX_EXTENDED_IMAGE_BYTE_START;
69 }
70
71 bool ImageManager::set_animation_frame_update(int frame)
72 {
73         if(frame != animation_frame) {
74                 animation_frame = frame;
75
76                 for(size_t slot = 0; slot < images.size(); slot++)
77                         if(images[slot] && images[slot]->animated)
78                                 return true;
79
80                 for(size_t slot = 0; slot < float_images.size(); slot++)
81                         if(float_images[slot] && float_images[slot]->animated)
82                                 return true;
83         }
84         
85         return false;
86 }
87
88 bool ImageManager::is_float_image(const string& filename, void *builtin_data, bool& is_linear)
89 {
90         bool is_float = false;
91         is_linear = false;
92
93         if(builtin_data) {
94                 if(builtin_image_info_cb) {
95                         int width, height, channels;
96                         builtin_image_info_cb(filename, builtin_data, is_float, width, height, channels);
97                 }
98
99                 if(is_float)
100                         is_linear = true;
101
102                 return is_float;
103         }
104
105         ImageInput *in = ImageInput::create(filename);
106
107         if(in) {
108                 ImageSpec spec;
109
110                 if(in->open(filename, spec)) {
111                         /* check the main format, and channel formats;
112                          * if any take up more than one byte, we'll need a float texture slot */
113                         if(spec.format.basesize() > 1) {
114                                 is_float = true;
115                                 is_linear = true;
116                         }
117
118                         for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
119                                 if(spec.channelformats[channel].basesize() > 1) {
120                                         is_float = true;
121                                         is_linear = true;
122                                 }
123                         }
124
125                         /* basic color space detection, not great but better than nothing
126                          * before we do OpenColorIO integration */
127                         if(is_float) {
128                                 string colorspace = spec.get_string_attribute("oiio:ColorSpace");
129
130                                 is_linear = !(colorspace == "sRGB" ||
131                                               colorspace == "GammaCorrected" ||
132                                                           strcmp(in->format_name(), "png") == 0);
133                         }
134                         else
135                                 is_linear = false;
136
137                         in->close();
138                 }
139
140                 delete in;
141         }
142
143         return is_float;
144 }
145
146 int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear)
147 {
148         Image *img;
149         size_t slot;
150
151         /* load image info and find out if we need a float texture */
152         is_float = (pack_images)? false: is_float_image(filename, builtin_data, is_linear);
153
154         if(is_float) {
155                 /* find existing image */
156                 for(slot = 0; slot < float_images.size(); slot++) {
157                         if(float_images[slot] && float_images[slot]->filename == filename) {
158                                 float_images[slot]->users++;
159                                 return slot;
160                         }
161                 }
162
163                 /* find free slot */
164                 for(slot = 0; slot < float_images.size(); slot++) {
165                         if(!float_images[slot])
166                                 break;
167                 }
168
169                 if(slot == float_images.size()) {
170                         /* max images limit reached */
171                         if(float_images.size() == TEX_NUM_FLOAT_IMAGES) {
172                                 printf("ImageManager::add_image: float image limit reached %d, skipping '%s'\n",
173                                        tex_num_float_images, filename.c_str());
174                                 return -1;
175                         }
176
177                         float_images.resize(float_images.size() + 1);
178                 }
179
180                 /* add new image */
181                 img = new Image();
182                 img->filename = filename;
183                 img->builtin_data = builtin_data;
184                 img->need_load = true;
185                 img->animated = animated;
186                 img->users = 1;
187
188                 float_images[slot] = img;
189         }
190         else {
191                 for(slot = 0; slot < images.size(); slot++) {
192                         if(images[slot] && images[slot]->filename == filename) {
193                                 images[slot]->users++;
194                                 return slot+tex_image_byte_start;
195                         }
196                 }
197
198                 /* find free slot */
199                 for(slot = 0; slot < images.size(); slot++) {
200                         if(!images[slot])
201                                 break;
202                 }
203
204                 if(slot == images.size()) {
205                         /* max images limit reached */
206                         if(images.size() == tex_num_images) {
207                                 printf("ImageManager::add_image: byte image limit reached %d, skipping '%s'\n",
208                                        tex_num_images, filename.c_str());
209                                 return -1;
210                         }
211
212                         images.resize(images.size() + 1);
213                 }
214
215                 /* add new image */
216                 img = new Image();
217                 img->filename = filename;
218                 img->builtin_data = builtin_data;
219                 img->need_load = true;
220                 img->animated = animated;
221                 img->users = 1;
222
223                 images[slot] = img;
224
225                 slot += tex_image_byte_start;
226         }
227         need_update = true;
228
229         return slot;
230 }
231
232 void ImageManager::remove_image(const string& filename, void *builtin_data)
233 {
234         size_t slot;
235
236         for(slot = 0; slot < images.size(); slot++) {
237                 if(images[slot] && images[slot]->filename == filename && images[slot]->builtin_data == builtin_data) {
238                         /* decrement user count */
239                         images[slot]->users--;
240                         assert(images[slot]->users >= 0);
241
242                         /* don't remove immediately, rather do it all together later on. one of
243                          * the reasons for this is that on shader changes we add and remove nodes
244                          * that use them, but we do not want to reload the image all the time. */
245                         if(images[slot]->users == 0)
246                                 need_update = true;
247
248                         break;
249                 }
250         }
251
252         if(slot == images.size()) {
253                 /* see if it's in a float texture slot */
254                 for(slot = 0; slot < float_images.size(); slot++) {
255                         if(float_images[slot] && float_images[slot]->filename == filename && float_images[slot]->builtin_data == builtin_data) {
256                                 /* decrement user count */
257                                 float_images[slot]->users--;
258                                 assert(float_images[slot]->users >= 0);
259
260                                 /* don't remove immediately, rather do it all together later on. one of
261                                  * the reasons for this is that on shader changes we add and remove nodes
262                                  * that use them, but we do not want to reload the image all the time. */
263                                 if(float_images[slot]->users == 0)
264                                         need_update = true;
265
266                                 break;
267                         }
268                 }
269         }
270 }
271
272 bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
273 {
274         if(img->filename == "")
275                 return false;
276
277         ImageInput *in = NULL;
278         int width, height, components;
279
280         if(!img->builtin_data) {
281                 /* load image from file through OIIO */
282                 in = ImageInput::create(img->filename);
283
284                 if(!in)
285                         return false;
286
287                 ImageSpec spec;
288
289                 if(!in->open(img->filename, spec)) {
290                         delete in;
291                         return false;
292                 }
293
294                 width = spec.width;
295                 height = spec.height;
296                 components = spec.nchannels;
297         }
298         else {
299                 /* load image using builtin images callbacks */
300                 if(!builtin_image_info_cb || !builtin_image_pixels_cb)
301                         return false;
302
303                 bool is_float;
304                 builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components);
305         }
306
307         /* we only handle certain number of components */
308         if(!(components == 1 || components == 3 || components == 4)) {
309                 if(in) {
310                         in->close();
311                         delete in;
312                 }
313
314                 return false;
315         }
316
317         /* read RGBA pixels */
318         uchar *pixels = (uchar*)tex_img.resize(width, height);
319         int scanlinesize = width*components*sizeof(uchar);
320
321         if(in) {
322                 in->read_image(TypeDesc::UINT8,
323                         (uchar*)pixels + (height-1)*scanlinesize,
324                         AutoStride,
325                         -scanlinesize,
326                         AutoStride);
327
328                 in->close();
329                 delete in;
330         }
331         else {
332                 builtin_image_pixels_cb(img->filename, img->builtin_data, pixels);
333         }
334
335         if(components == 3) {
336                 for(int i = width*height-1; i >= 0; i--) {
337                         pixels[i*4+3] = 255;
338                         pixels[i*4+2] = pixels[i*3+2];
339                         pixels[i*4+1] = pixels[i*3+1];
340                         pixels[i*4+0] = pixels[i*3+0];
341                 }
342         }
343         else if(components == 1) {
344                 for(int i = width*height-1; i >= 0; i--) {
345                         pixels[i*4+3] = 255;
346                         pixels[i*4+2] = pixels[i];
347                         pixels[i*4+1] = pixels[i];
348                         pixels[i*4+0] = pixels[i];
349                 }
350         }
351
352         return true;
353 }
354
355 bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_img)
356 {
357         if(img->filename == "")
358                 return false;
359
360         ImageInput *in = NULL;
361         int width, height, components;
362
363         if(!img->builtin_data) {
364                 /* load image from file through OIIO */
365                 in = ImageInput::create(img->filename);
366
367                 if(!in)
368                         return false;
369
370                 ImageSpec spec;
371
372                 if(!in->open(img->filename, spec)) {
373                         delete in;
374                         return false;
375                 }
376
377                 /* we only handle certain number of components */
378                 width = spec.width;
379                 height = spec.height;
380                 components = spec.nchannels;
381         }
382         else {
383                 /* load image using builtin images callbacks */
384                 if(!builtin_image_info_cb || !builtin_image_float_pixels_cb)
385                         return false;
386
387                 bool is_float;
388                 builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components);
389         }
390
391         if(!(components == 1 || components == 3 || components == 4)) {
392                 if(in) {
393                         in->close();
394                         delete in;
395                 }
396                 return false;
397         }
398
399         /* read RGBA pixels */
400         float *pixels = (float*)tex_img.resize(width, height);
401         int scanlinesize = width*components*sizeof(float);
402
403         if(in) {
404                 in->read_image(TypeDesc::FLOAT,
405                         (uchar*)pixels + (height-1)*scanlinesize,
406                         AutoStride,
407                         -scanlinesize,
408                         AutoStride);
409
410                 in->close();
411                 delete in;
412         }
413         else {
414                 builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels);
415         }
416
417         if(components == 3) {
418                 for(int i = width*height-1; i >= 0; i--) {
419                         pixels[i*4+3] = 1.0f;
420                         pixels[i*4+2] = pixels[i*3+2];
421                         pixels[i*4+1] = pixels[i*3+1];
422                         pixels[i*4+0] = pixels[i*3+0];
423                 }
424         }
425         else if(components == 1) {
426                 for(int i = width*height-1; i >= 0; i--) {
427                         pixels[i*4+3] = 1.0f;
428                         pixels[i*4+2] = pixels[i];
429                         pixels[i*4+1] = pixels[i];
430                         pixels[i*4+0] = pixels[i];
431                 }
432         }
433
434         return true;
435 }
436
437 void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int slot, Progress *progress)
438 {
439         if(progress->get_cancel())
440                 return;
441         if(osl_texture_system)
442                 return;
443
444         Image *img;
445         bool is_float;
446
447         if(slot >= tex_image_byte_start) {
448                 img = images[slot - tex_image_byte_start];
449                 is_float = false;
450         }
451         else {
452                 img = float_images[slot];
453                 is_float = true;
454         }
455
456         if(is_float) {
457                 string filename = path_filename(float_images[slot]->filename);
458                 progress->set_status("Updating Images", "Loading " + filename);
459
460                 device_vector<float4>& tex_img = dscene->tex_float_image[slot];
461
462                 if(tex_img.device_pointer) {
463                         thread_scoped_lock device_lock(device_mutex);
464                         device->tex_free(tex_img);
465                 }
466
467                 if(!file_load_float_image(img, tex_img)) {
468                         /* on failure to load, we set a 1x1 pixels pink image */
469                         float *pixels = (float*)tex_img.resize(1, 1);
470
471                         pixels[0] = TEX_IMAGE_MISSING_R;
472                         pixels[1] = TEX_IMAGE_MISSING_G;
473                         pixels[2] = TEX_IMAGE_MISSING_B;
474                         pixels[3] = TEX_IMAGE_MISSING_A;
475                 }
476
477                 string name;
478
479                 if(slot >= 10) name = string_printf("__tex_image_float_0%d", slot);
480                 else name = string_printf("__tex_image_float_00%d", slot);
481
482                 if(!pack_images) {
483                         thread_scoped_lock device_lock(device_mutex);
484                         device->tex_alloc(name.c_str(), tex_img, true, true);
485                 }
486         }
487         else {
488                 string filename = path_filename(images[slot - tex_image_byte_start]->filename);
489                 progress->set_status("Updating Images", "Loading " + filename);
490
491                 device_vector<uchar4>& tex_img = dscene->tex_image[slot - tex_image_byte_start];
492
493                 if(tex_img.device_pointer) {
494                         thread_scoped_lock device_lock(device_mutex);
495                         device->tex_free(tex_img);
496                 }
497
498                 if(!file_load_image(img, tex_img)) {
499                         /* on failure to load, we set a 1x1 pixels pink image */
500                         uchar *pixels = (uchar*)tex_img.resize(1, 1);
501
502                         pixels[0] = (TEX_IMAGE_MISSING_R * 255);
503                         pixels[1] = (TEX_IMAGE_MISSING_G * 255);
504                         pixels[2] = (TEX_IMAGE_MISSING_B * 255);
505                         pixels[3] = (TEX_IMAGE_MISSING_A * 255);
506                 }
507
508                 string name;
509
510                 if(slot >= 10) name = string_printf("__tex_image_0%d", slot);
511                 else name = string_printf("__tex_image_00%d", slot);
512
513                 if(!pack_images) {
514                         thread_scoped_lock device_lock(device_mutex);
515                         device->tex_alloc(name.c_str(), tex_img, true, true);
516                 }
517         }
518
519         img->need_load = false;
520 }
521
522 void ImageManager::device_free_image(Device *device, DeviceScene *dscene, int slot)
523 {
524         Image *img;
525         bool is_float;
526
527         if(slot >= tex_image_byte_start) {
528                 img = images[slot - tex_image_byte_start];
529                 is_float = false;
530         }
531         else {
532                 img = float_images[slot];
533                 is_float = true;
534         }
535
536         if(img) {
537                 if(osl_texture_system) {
538 #ifdef WITH_OSL
539                         ustring filename(images[slot]->filename);
540                         ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
541 #endif
542                 }
543                 else if(is_float) {
544                         device_vector<float4>& tex_img = dscene->tex_float_image[slot];
545
546                         if(tex_img.device_pointer) {
547                                 thread_scoped_lock device_lock(device_mutex);
548                                 device->tex_free(tex_img);
549                         }
550
551                         tex_img.clear();
552
553                         delete float_images[slot];
554                         float_images[slot] = NULL;
555                 }
556                 else {
557                         device_vector<uchar4>& tex_img = dscene->tex_image[slot - tex_image_byte_start];
558
559                         if(tex_img.device_pointer) {
560                                 thread_scoped_lock device_lock(device_mutex);
561                                 device->tex_free(tex_img);
562                         }
563
564                         tex_img.clear();
565
566                         delete images[slot - tex_image_byte_start];
567                         images[slot - tex_image_byte_start] = NULL;
568                 }
569         }
570 }
571
572 void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& progress)
573 {
574         if(!need_update)
575                 return;
576
577         TaskPool pool;
578
579         for(size_t slot = 0; slot < images.size(); slot++) {
580                 if(!images[slot])
581                         continue;
582
583                 if(images[slot]->users == 0) {
584                         device_free_image(device, dscene, slot + tex_image_byte_start);
585                 }
586                 else if(images[slot]->need_load) {
587                         if(!osl_texture_system) 
588                                 pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, slot + tex_image_byte_start, &progress));
589                 }
590         }
591
592         for(size_t slot = 0; slot < float_images.size(); slot++) {
593                 if(!float_images[slot])
594                         continue;
595
596                 if(float_images[slot]->users == 0) {
597                         device_free_image(device, dscene, slot);
598                 }
599                 else if(float_images[slot]->need_load) {
600                         if(!osl_texture_system) 
601                                 pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, slot, &progress));
602                 }
603         }
604
605         pool.wait_work();
606
607         if(pack_images)
608                 device_pack_images(device, dscene, progress);
609
610         need_update = false;
611 }
612
613 void ImageManager::device_pack_images(Device *device, DeviceScene *dscene, Progress& progess)
614 {
615         /* for OpenCL, we pack all image textures inside a single big texture, and
616          * will do our own interpolation in the kernel */
617         size_t size = 0;
618
619         for(size_t slot = 0; slot < images.size(); slot++) {
620                 if(!images[slot])
621                         continue;
622
623                 device_vector<uchar4>& tex_img = dscene->tex_image[slot];
624                 size += tex_img.size();
625         }
626
627         uint4 *info = dscene->tex_image_packed_info.resize(images.size());
628         uchar4 *pixels = dscene->tex_image_packed.resize(size);
629
630         size_t offset = 0;
631
632         for(size_t slot = 0; slot < images.size(); slot++) {
633                 if(!images[slot])
634                         continue;
635
636                 device_vector<uchar4>& tex_img = dscene->tex_image[slot];
637
638                 info[slot] = make_uint4(tex_img.data_width, tex_img.data_height, offset, 1);
639
640                 memcpy(pixels+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
641                 offset += tex_img.size();
642         }
643
644         if(dscene->tex_image_packed.size())
645                 device->tex_alloc("__tex_image_packed", dscene->tex_image_packed);
646         if(dscene->tex_image_packed_info.size())
647                 device->tex_alloc("__tex_image_packed_info", dscene->tex_image_packed_info);
648 }
649
650 void ImageManager::device_free(Device *device, DeviceScene *dscene)
651 {
652         for(size_t slot = 0; slot < images.size(); slot++)
653                 device_free_image(device, dscene, slot + tex_image_byte_start);
654         for(size_t slot = 0; slot < float_images.size(); slot++)
655                 device_free_image(device, dscene, slot);
656
657         device->tex_free(dscene->tex_image_packed);
658         device->tex_free(dscene->tex_image_packed_info);
659
660         dscene->tex_image_packed.clear();
661         dscene->tex_image_packed_info.clear();
662
663         images.clear();
664         float_images.clear();
665 }
666
667 CCL_NAMESPACE_END
668