Two in one:
[blender.git] / source / blender / src / imasel.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #ifndef WIN32
38 #include <unistd.h>
39 #else
40 #include "BLI_winstuff.h"
41 #include <io.h>
42 #include <direct.h>
43 #endif   
44 #include <fcntl.h>
45 #include "MEM_guardedalloc.h"
46
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"
49
50 #include "IMB_imbuf_types.h"
51 #include "IMB_imbuf.h"
52
53 #include "DNA_screen_types.h"
54 #include "DNA_space_types.h"
55
56 #include "BKE_utildefines.h"
57 #include "BKE_global.h"
58
59 #include "BIF_imasel.h"
60 #include "BIF_space.h"
61 #include "BIF_screen.h"
62
63 #include "blendef.h"
64 #include "mydevice.h"
65
66 #ifndef WIN32
67 #include <dirent.h>
68 #endif
69
70 #include <sys/stat.h>
71 #include "datatoc.h"
72
73 /* locals */
74 void longtochar(char *des, unsigned int *src, int size);
75 void chartolong(unsigned int *des, char *src, int size);
76 int dir_compare(const void *a1, const void *a2);
77 void issort( int te, ImaDir **firstentry);
78 int ima_compare(const void *a1, const void *a2);
79 void imsort(OneSelectableIma **firstentry);
80 void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima);  
81 void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry);
82
83 /* implementation */
84 int  bitset(int l,  int bit)
85 {       return (( l & bit) == bit);  }
86
87 void longtochar(char *des, unsigned int *src, int size)
88 {       int i;for (i = 0; i<size; i++){ des[i] = src[i] & 0xFF; }}
89
90 void chartolong(unsigned int *des, char *src, int size)
91 {       int i;for (i = 0; i<size; i++){ des[i] = src[i]; }}
92
93 int dir_compare(const void *a1, const void *a2)
94 {
95         ImaDir **in1, **in2;
96         ImaDir *use1, *use2;
97
98         in1= (ImaDir **)a1;
99         in2= (ImaDir **)a2;
100
101         use1 = *in1;
102         use2 = *in2;
103         
104         return BLI_strcasecmp(use1->name,  use2->name);
105 }
106
107 void issort( int te, ImaDir **firstentry)
108 {
109         ImaDir **sort;
110         ImaDir *use;
111         int i = 0;
112         
113         sort = MEM_mallocN(te * sizeof(void *),  "dir Sorteer temp");
114         use = *firstentry;
115         
116         while (use){
117                 sort[i++] = use;
118                 use = use->next;
119         }
120         
121         qsort (sort, te, sizeof(void *), dir_compare);
122         
123         *firstentry = sort[0];
124         use = *firstentry;
125         
126         
127         for (i=0; i<te; i++){
128                 if (i != 0)    use->prev = sort[i-1]; else use->prev = 0;
129                 if (i != te-1) use->next = sort[i+1]; else use->next = 0;
130         
131                 use = use->next;
132         }
133         
134         MEM_freeN(sort);
135 }
136
137
138 int ima_compare(const void *a1, const void *a2)
139 {
140         OneSelectableIma **in1, **in2;
141         OneSelectableIma *use1, *use2;
142
143         in1= (OneSelectableIma **)a1;
144         in2= (OneSelectableIma **)a2;
145
146         use1 = *in1; use2 = *in2;
147         return BLI_strcasecmp(use1->file_name,  use2->file_name);
148 }
149
150 void imsort(OneSelectableIma **firstentry)
151 {
152         OneSelectableIma **sort;
153         OneSelectableIma *use;
154         int tot = 0, i = 0;
155         
156         use = *firstentry;
157         while (use){
158                 tot++;
159                 use = use->next;
160         }
161         
162         if (tot){
163                 sort = MEM_mallocN(tot * sizeof(void *),  "Sorteer imsort temp");
164                 use = *firstentry;
165                 while (use){
166                         sort[i++] = use;
167                         use = use->next;
168                 }
169                 
170                 qsort (sort, tot, sizeof(void *), ima_compare);
171                 
172                 *firstentry = sort[0];
173                 use = *firstentry;
174                 for (i=0; i<tot; i++){
175                         if (i != 0)     use->prev = sort[i-1]; else use->prev = 0;
176                         if (i != tot-1) use->next = sort[i+1]; else use->next = 0;
177                 
178                         use = use->next;
179                 }
180                 MEM_freeN(sort);
181         }
182 }
183
184 static int write_msb_int(int fd, int i) {
185         unsigned int ui= (unsigned int) i;
186         unsigned char buf[4];
187         buf[0]= (ui>>24)&0xFF;
188         buf[1]= (ui>>16)&0xFF;
189         buf[2]= (ui>>8)&0xFF;
190         buf[3]= (ui>>0)&0xFF;
191         return write(fd, buf, 4);
192 }
193 static int write_msb_short(int fd, short s) {
194         unsigned short us= (unsigned short) s;
195         unsigned char buf[2];
196         buf[0]= (us>>8)&0xFF;
197         buf[1]= (us>>0)&0xFF;
198         return write(fd, buf, 2);
199 }
200
201 static int read_msb_int(int fd, int *i_r) {
202         unsigned char buf[4];
203         int rcount= read(fd, buf, 4);
204         
205         if (i_r)
206                 *i_r= (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3]<<0);
207
208         return rcount;
209 }
210 static int read_msb_short(int fd, short *s_r) {
211         unsigned char buf[2];
212         int rcount= read(fd, buf, 2);
213         
214         if (s_r)
215                 *s_r= (buf[0]<<8)|(buf[1]<<0);
216
217         return rcount;
218 }
219
220 void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima)
221 {
222         int  file;
223         char name[FILE_MAXDIR+FILE_MAXFILE];
224         
225         if ( bitset (simasel->fase, IMS_WRITE_NO_BIP)) return;
226         
227         strcpy(name, simasel->dir);
228         strcat(name, ".Bpib");
229         
230         file = open(name, O_BINARY|O_APPEND | O_RDWR | O_CREAT, 0666);
231         if (file == -1) {
232                 /* printf("Could not write .Bpib file in dir %s\n", simasel->dir); */
233                 simasel->fase |= IMS_WRITE_NO_BIP;
234                 return;
235         }
236         
237         lseek(file, 0, SEEK_END);
238         
239         write(file, "BIP2", 4);
240         write_msb_int(file,             ima->ibuf_type);
241         write_msb_int(file,             0);
242         write_msb_int(file,             0);
243         write_msb_int(file,             0);
244         write_msb_short(file,   ima->cmap);
245         write_msb_short(file,   ima->image);
246         write_msb_short(file,   ima->draw_me);
247         write_msb_short(file,   ima->rt);
248         write_msb_short(file,   ima->sx);
249         write_msb_short(file,   ima->sy);
250         write_msb_short(file,   ima->ex);
251         write_msb_short(file,   ima->ey);
252         write_msb_short(file,   ima->dw);
253         write_msb_short(file,   ima->dh);
254         write_msb_short(file,   ima->selectable);
255         write_msb_short(file,   ima->selected);
256         write_msb_int(file,             ima->mtime);
257         write_msb_int(file,             ima->disksize);
258         write(file, ima->file_name, 64);
259         write_msb_short(file,   ima->orgx);
260         write_msb_short(file,   ima->orgy);
261         write_msb_short(file,   ima->orgd);
262         write_msb_short(file,   ima->anim);
263         write_msb_int(file,             0); /* pad to 128 boundary */
264         write(file, ima->pict_rect, 3968);      
265
266         close(file);
267 }
268
269 void write_new_pib(SpaceImaSel *simasel)
270 {
271         OneSelectableIma *ima;
272         char name[FILE_MAXDIR+FILE_MAXFILE];
273         
274         strcpy(name, simasel->dir);
275         strcat(name, ".Bpib");
276         remove(name);
277         
278         ima = simasel->first_sel_ima;
279         while (ima) {
280                 append_pib(simasel, ima);
281                 ima = ima->next;
282         }
283 }
284
285 void free_ima_dir(ImaDir *firstdir)
286 {
287         ImaDir *n;
288         
289         while(firstdir){
290                 n = firstdir->next;
291                 MEM_freeN(firstdir);
292                 firstdir = n;
293         }
294 }
295
296 void free_sel_ima(OneSelectableIma *firstima)
297 {
298         OneSelectableIma *n;
299         
300         while(firstima){
301                 
302                 if (firstima->pict) {
303                         IMB_freeImBuf(firstima->pict);
304                 }
305                 n = firstima->next;
306                 MEM_freeN(firstima);
307                 firstima = n;
308         }
309 }
310
311 void check_for_pib(SpaceImaSel *simasel)
312 {
313         ImaDir  *direntry;
314         
315         direntry = simasel->firstfile;
316         while(direntry){
317                 if ((strlen(direntry->name) > 4) && (0==strcmp(direntry->name, ".Bpib")) ){
318                         simasel->fase |= IMS_FOUND_BIP;
319                         direntry = 0;
320                 }else{
321                         direntry = direntry->next;
322                 }
323         }
324 }
325
326 void clear_ima_dir(SpaceImaSel *simasel)
327 {
328         if(simasel->first_sel_ima)      free_sel_ima(simasel->first_sel_ima);
329         if(simasel->firstdir)           free_ima_dir(simasel->firstdir);
330         if(simasel->firstfile)          free_ima_dir(simasel->firstfile);
331
332         simasel->first_sel_ima  =  0;
333         simasel->firstdir               =  0;
334         simasel->firstfile              =  0;
335         
336         simasel->totaldirs              =  0;
337         simasel->totalfiles             =  0;
338         simasel->totalima               =  0;
339         simasel->topdir                 = -1;
340         simasel->topfile                = -1;
341         simasel->topima                 =  0;
342         simasel->image_slider   =  0.0;
343         simasel->slider_height  =  0.0;
344         simasel->slider_space   =  0.0;
345         simasel->hilite                 = -1;
346         simasel->curimax                =  0;
347         simasel->curimay                =  0;
348         
349         simasel->total_selected =  0;
350         simasel->fase                   =  0;
351         simasel->subfase                =  0;
352         simasel->imafase                =  0;
353         simasel->ima_redraw     =  0;
354 }
355
356 int get_ima_dir(char *dirname, int dtype, int *td, ImaDir **first)
357 {
358         DIR *dirp;
359         struct dirent *dep;
360         struct ImaDir *temp;
361         struct ImaDir *dnext = NULL, *fnext;
362         struct stat status;
363         char olddir[FILE_MAXDIR+FILE_MAXFILE];
364         char getdirname[FILE_MAXDIR+FILE_MAXFILE];
365         int  /*  i=0, */ tot=0; 
366         int isdir;
367         
368         if(!BLI_getwdN(olddir)) return -1;
369         
370         if (chdir(dirname) == -1) return(-1);
371         
372         strcpy(getdirname, ".");
373         
374         dirp = (DIR *) opendir(getdirname);
375         if (dirp == NULL) return (-1);
376
377         waitcursor(1);
378
379         while((dep = (struct dirent*) readdir(dirp)) != NULL){
380                 
381                 strcpy(getdirname, dirname);
382                 strcat(getdirname,dep->d_name);
383                 
384                 stat(getdirname, &status);
385                 isdir = S_ISDIR(status.st_mode);
386                 
387                 if ( ((dtype == IMS_DIR)  && isdir) || ((dtype == IMS_FILE)  && !isdir)){                       
388                         /* yes, searching for this type */
389                         tot++;
390                         if (tot == 1){
391                                 dnext   = MEM_callocN(sizeof(struct ImaDir), "get first");
392                                 *first  = dnext;
393                                 
394                                 dnext->prev     = 0;
395                                 dnext->next     = 0;
396                         }else{
397                                 fnext               = MEM_callocN(sizeof(struct ImaDir), "get nextdir");
398                                 dnext->next     = fnext;
399                                 
400                                 temp  = dnext;
401                                 dnext = fnext;
402                                 
403                                 dnext ->prev     = temp;
404                                 dnext ->next     = 0;
405                         }
406                         
407                         dnext->type     = dtype;
408                         dnext->selected = 0;
409                         dnext->hilite   = 0;
410                         
411                         dnext->mtime    = status.st_ctime;
412                         dnext->size     = (int)status.st_size;
413                         strcpy(dnext->name, dep->d_name);
414                 }
415         }
416         closedir(dirp);
417         
418         if (tot) issort(tot, first);
419         
420         waitcursor(0);
421         
422         *td = tot;
423         
424         chdir (olddir);
425         
426         return (tot);
427 }
428
429 void imadir_parent(SpaceImaSel *simasel)
430 {
431
432 #ifdef WIN32
433         if (strlen(simasel->dir) > 1){
434                 simasel->dir[strlen(simasel->dir)-1] = 0;
435                 while(simasel->dir[strlen(simasel->dir)-1] != '\\'){
436                         if(strlen(simasel->dir)==0) break;
437                         simasel->dir[strlen(simasel->dir)-1] = 0;       
438                 }
439         }
440 #else
441         if (strlen(simasel->dir) > 1){
442                 simasel->dir[strlen(simasel->dir)-1] = 0;
443                 while(simasel->dir[strlen(simasel->dir)-1] != '/') {
444                         if(strlen(simasel->dir)==0) break;
445                         simasel->dir[strlen(simasel->dir)-1] = 0;       
446                 }
447         }
448 #endif
449 }
450
451
452 void get_next_image(SpaceImaSel *simasel)
453 {
454         OneSelectableIma * ima;
455         ImBuf            * ibuf;
456         struct anim      * anim;
457         int     i = 0, size;
458         char    name[FILE_MAXDIR+FILE_MAXFILE];
459         
460         ima = simasel->first_sel_ima;
461         if (ima == 0){
462                 simasel->imafase = 0;
463                 simasel->fase |=  IMS_KNOW_IMA;
464                 simasel->fase &= ~IMS_DOTHE_IMA;
465                 return; 
466         }
467         if (simasel->imafase > simasel->totalima){
468                 simasel->imafase = 0;
469                 simasel->fase &= ~IMS_DOTHE_IMA;
470                 simasel->fase |=  IMS_KNOW_IMA;
471         }
472         
473         ima = simasel->first_sel_ima;
474         i = 0;
475         while(i < simasel->imafase){
476                 if ((ima) && (ima->next)) ima = ima->next;
477                 i++;
478         }
479         
480         if (ima->image == 0) {
481                 if (ima->anim == 1) {
482                         /* open movie, get len, get middle picture */
483                         
484                         strcpy(name, simasel->dir);
485                         strcat(name, ima->file_name);
486
487                         anim = IMB_open_anim(name, IB_rect);
488                         
489                         if (anim == 0) {
490                                 // ibuf= IMB_loadiffmem((int*)datatoc_cmovie_tga, IB_rect);
491                                 ibuf= IMB_ibImageFromMemory((int *)datatoc_cmovie_tga, datatoc_cmovie_tga_size, IB_rect);
492                         }
493                         else{
494                                 int animlen;
495                                 
496                                 ibuf = IMB_anim_nextpic(anim);
497                                 IMB_freeImBuf(ibuf);
498                                 
499                                 animlen= IMB_anim_get_duration(anim);
500                                 ibuf = IMB_anim_absolute(anim, animlen / 2);
501
502                                 if(ibuf) {
503                                         //get icon dimensions for movie
504                                         ima->orgx = ibuf->x;
505                                         ima->orgy = ibuf->y;
506 //                                      ima->orgd = ibuf->depth;
507
508                                         if (ima->orgx > ima->orgy){
509                                                 ima->dw = 64;
510                                                 ima->dh = (short)(62 * ((float)ima->orgy / (float)ima->orgx));
511                                         }else{
512                                                 ima->dw = (short)(64 * ((float)ima->orgx / (float)ima->orgy));
513                                                 ima->dh = 62;
514                                         }
515                                 }
516                                 
517                                 IMB_free_anim(anim);
518                         }
519                 }
520                 else {
521                         
522                         strcpy(name, simasel->dir);
523                         strcat(name, ima->file_name);
524
525                         ibuf = IMB_loadiffname(name, IB_rect);
526                         if(ibuf && ibuf->zbuf) IMB_freezbufImBuf(ibuf);
527                 }
528                 
529                 if (ibuf){
530                         if (ima->dw < 4) ima->dw = 4;
531                         if (ima->dh < 4) ima->dh = 4;
532                         
533                         IMB_scaleImBuf(ibuf, ima->dw, ima->dh);
534                         /* the whole cmap system is wacko */
535                         
536                         if (G.order==B_ENDIAN)
537                                 IMB_convert_rgba_to_abgr(ibuf);
538                         
539                         ibuf->mincol =   0;
540                         ibuf->maxcol = 256;
541                         ibuf->cbits  =   5;
542                         ibuf->depth  =   8;
543                         
544                         IMB_freecmapImBuf(ibuf);
545                         ibuf->cmap = simasel->cmap->cmap;
546                         
547                         IMB_converttocmap(ibuf);
548                         
549                         /* copy ibuf->rect to ima->pict_rect */ 
550                         size = ima->dw * ima->dh; if (size > 3968) size = 3968;
551                         longtochar(ima->pict_rect, ibuf->rect, size); 
552
553                         IMB_applycmap(ibuf);
554                         IMB_convert_rgba_to_abgr(ibuf);
555                         
556                         if (ima->pict) IMB_freeImBuf(ima->pict);
557                         ima->pict = ibuf;
558                         ibuf = 0;
559                         ima->cmap  = 1;
560                         ima->image = 1;
561                         
562                         append_pib(simasel, ima);
563                 }
564         }
565         simasel->ima_redraw++;
566         simasel->imafase ++;
567         if (simasel->imafase == simasel->totalima){
568                 simasel->imafase = 0;
569                 simasel->fase &= ~IMS_DOTHE_IMA;
570                 simasel->fase |= IMS_KNOW_IMA;
571         }
572 }
573
574 void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry)
575 {
576         OneSelectableIma *ima, *prev_ima;
577         ImBuf   *ibuf;
578         char    name[FILE_MAXDIR+FILE_MAXFILE];
579         
580         strcpy(name ,  simasel->dir);
581         strcat(name ,  direntry->name);
582         
583         prev_ima = simasel->first_sel_ima;
584         while((prev_ima)&&(prev_ima->next)){
585                 prev_ima = prev_ima->next;
586         }
587         
588         ima = MEM_callocN(sizeof(OneSelectableIma), "OSIbip");
589         if (direntry->type == IMS_IMA){
590                 /* Picture is an Image */
591                 ibuf = IMB_loadiffname(name, IB_test);
592                 if (ibuf){
593                         ima->anim         = 0;
594                         ima->pict     = ibuf;
595                         ima->ibuf_type= ibuf->ftype;
596                         ima->orgx     = ibuf->x;
597                         ima->orgy     = ibuf->y;
598                         ima->orgd     = ibuf->depth;
599                         
600                         ima->dw    = 64;
601                         ima->dh    = 51;
602                         ima->cmap  =  0;
603                         ima->image =  0;  
604                         if (ima->orgx > ima->orgy){
605                                 ima->dw = 64;
606                                 ima->dh = (short)(62 * ((float)ima->orgy / (float)ima->orgx));
607                         }else{
608                                 ima->dw = (short)(64 * ((float)ima->orgx / (float)ima->orgy));
609                                 ima->dh = 62;
610                         }
611                 }else{
612                         printf("%s image with no imbuf ???\n", name);
613                 }
614                 ibuf = 0;       
615         }else{
616                 /* Picture is an Animation */
617         
618                 ima->pict     =  0;
619                 ima->anim         =  1;
620                 ima->ibuf_type=  0;
621                 ima->orgx         = 64;
622                 ima->orgy     = 51;
623                 ima->orgd     = 24;
624                 
625                 ima->dw    = 64;
626                 ima->dh    = 51;
627                 ima->cmap  =  0;
628                 ima->image =  0;  
629         }
630                 
631         strcpy(name, direntry->name); name[63] = 0;
632         strcpy(ima->file_name, name);
633         ima->disksize = (int)direntry->size;
634         ima->mtime    = (int)direntry->mtime;
635         
636         ima->next = 0;
637         ima->prev = prev_ima;
638
639         if (prev_ima)   {       
640                 prev_ima->next = ima;
641         }else{   
642                 simasel->first_sel_ima =  ima;  
643         }
644         
645         simasel->ima_redraw++;
646         simasel->totalima++;
647 }
648
649
650 void get_file_info(SpaceImaSel *simasel)
651 {
652         OneSelectableIma *prev_ima;
653         ImaDir  *direntry;
654         char    name[FILE_MAXDIR+FILE_MAXFILE];
655         int     i = 0;
656         
657         if (!simasel->firstfile){
658                 simasel->subfase = 0;
659                 simasel->fase |= IMS_KNOW_INF;
660                 simasel->fase &= ~IMS_DOTHE_INF;
661                 return; 
662         }
663         if (simasel->subfase > simasel->totalfiles){
664                 simasel->subfase = 0;
665                 simasel->fase |= IMS_KNOW_INF;
666                 simasel->fase &= ~IMS_DOTHE_INF;
667         }
668
669         direntry = simasel->firstfile;
670         while(i < simasel->subfase){
671                 direntry = direntry->next;
672                 i++;
673         }
674         
675         prev_ima = simasel->first_sel_ima;
676         while((prev_ima)&&(prev_ima->next)){
677                 prev_ima = prev_ima->next;
678         }
679         
680         strcpy(name ,  simasel->dir);
681         strcat(name ,  direntry->name);
682         
683         if(direntry->name[0] == '.') {
684                 direntry->type = IMS_NOIMA;
685         } else {
686                 if (IMB_ispic(name)) {
687                         direntry->type = IMS_IMA;
688                 }else{
689                         if (IMB_isanim(name)) {
690                                 direntry->type = IMS_ANIM;
691                         }else{
692                                 direntry->type = IMS_NOIMA;
693                         }
694                 }
695         }
696         
697         if (direntry->type != IMS_NOIMA){       
698                 add_ima(1, simasel, direntry);
699         }
700         
701         simasel->subfase++;
702         
703         if (simasel->subfase == simasel->totalfiles){
704                 simasel->subfase = 0;
705                 simasel->fase |= IMS_KNOW_INF;
706                 simasel->fase &= ~IMS_DOTHE_INF;        
707         }
708 }
709
710 /* Note: the thumbnails are saved in ABGR format in the .Bpib
711 cache file */
712
713 void get_pib_file(SpaceImaSel *simasel)
714 {
715         ImaDir           *direntry, *prev_dir, *next_dir;
716         OneSelectableIma *ima, *prev_ima;
717         int flen;
718         int  dl, file, first, trd=0, rd, size, found, ima_added = 0;
719         char name[FILE_MAXDIR+FILE_MAXFILE];
720         
721         if (bitset(simasel->fase , IMS_KNOW_BIP)) return;
722         
723         waitcursor(1);
724
725         strcpy(name,  simasel->dir);
726         strcat(name,  ".Bpib");
727                 
728         file = open(name, O_BINARY|O_RDONLY);
729         
730         flen = BLI_filesize(file);
731
732         simasel->totalima = 0;
733         prev_ima = 0;
734         first = 1;
735         trd = 0;
736         
737         while(trd < flen){
738                 char header[5];
739                 
740                 ima = MEM_callocN(sizeof(OneSelectableIma), "Ima");
741                 
742                 rd= 0;
743                 rd+= read(file, header, 4);
744                 rd+= read_msb_int(file,         &ima->ibuf_type);
745                 rd+= read_msb_int(file,         NULL);
746                 rd+= read_msb_int(file,         NULL);
747                 rd+= read_msb_int(file,         NULL);
748                 rd+= read_msb_short(file,       &ima->cmap);
749                 rd+= read_msb_short(file,       &ima->image);
750                 rd+= read_msb_short(file,       &ima->draw_me);
751                 rd+= read_msb_short(file,       &ima->rt);
752                 rd+= read_msb_short(file,       &ima->sx);
753                 rd+= read_msb_short(file,       &ima->sy);
754                 rd+= read_msb_short(file,       &ima->ex);
755                 rd+= read_msb_short(file,       &ima->ey);
756                 rd+= read_msb_short(file,       &ima->dw);
757                 rd+= read_msb_short(file,       &ima->dh);
758                 rd+= read_msb_short(file,       &ima->selectable);
759                 rd+= read_msb_short(file,       &ima->selected);
760                 rd+= read_msb_int(file,         &ima->mtime);
761                 rd+= read_msb_int(file,         &ima->disksize);
762                 rd+= read(file, ima->file_name, 64);
763                 rd+= read_msb_short(file,       &ima->orgx);
764                 rd+= read_msb_short(file,       &ima->orgy);
765                 rd+= read_msb_short(file,       &ima->orgd);
766                 rd+= read_msb_short(file,       &ima->anim);
767                 rd+= read_msb_int(file,         NULL);
768                 rd+= read(file, ima->pict_rect, 3968);  
769
770                 found = 0;
771
772                 if (rd != sizeof(OneSelectableIma) || memcmp(header, "BIP2", 4)!=0) {
773                         printf("Error in Bpib file\n");
774                         strcpy(name, simasel->dir);
775                         strcat(name, ".Bpib");
776                         dl = remove(name);
777                         if (dl == 0) printf("corrupt Bpib file removed\n");
778                         trd = flen;
779                 } else {
780                                 /* find matching direntry (if possible) */
781                         for (direntry= simasel->firstfile; direntry; direntry= direntry->next)
782                                 if (BLI_streq(direntry->name, ima->file_name))
783                                         break;
784                         
785                         if (direntry) {
786                                 if (direntry->mtime == ima->mtime) {
787                                                 /*  ima found and same, load pic */
788                                         size = ima->dw * ima->dh;
789                                         if (size > 3968) size = 3968;
790                                         if (size) {
791                                                 ima->pict = IMB_allocImBuf(ima->dw, ima->dh, 24, IB_rect | IB_cmap, 0);
792                                                 chartolong(ima->pict->rect, ima->pict_rect, size);
793                                                 ima->pict->cmap = simasel->cmap->cmap;
794                                                 ima->pict->maxcol = 256;
795                                                 IMB_applycmap(ima->pict);
796                                                 IMB_convert_rgba_to_abgr(ima->pict);
797                                         }
798                                         ima->selected   = 0;
799                                         ima->selectable = 0;
800                                         
801                                         if(prev_ima) prev_ima->next = ima;
802                                         ima->next      = 0;
803                                         ima->prev      = prev_ima;
804                                         
805                                         prev_ima = ima;
806                 
807                                         if (first){ first = 0;simasel->first_sel_ima = ima; }
808                                         simasel->totalima++;
809                                         found = 1;
810                                 }
811                                         
812                                         /* remove direntry */
813                                 prev_dir = direntry->prev; 
814                                 next_dir = direntry->next;
815                                                         
816                                 if(prev_dir) prev_dir->next = next_dir; 
817                                 if(next_dir) next_dir->prev = prev_dir;
818                                                         
819                                 MEM_freeN(direntry);
820                         }
821                 }
822                 if (!found) MEM_freeN(ima);
823                 
824                 trd+=rd;
825         }
826         close(file);
827         
828         direntry = simasel->firstfile;
829         
830         while(direntry){
831                 
832                 strcpy(name ,  simasel->dir);
833                 strcat(name ,  direntry->name);
834                 
835                 if (IMB_ispic(name)) {
836                         direntry->type = IMS_IMA;
837                 }else{
838                         if (IMB_isanim(name)) {
839                                 direntry->type = IMS_ANIM;
840                         }else{
841                                 direntry->type = IMS_NOIMA;
842                         }
843                 }
844                 
845                 if (direntry->type != IMS_NOIMA){
846                         prev_ima = simasel->first_sel_ima;
847                         while((prev_ima)&&(prev_ima->next)){
848                                 prev_ima = prev_ima->next;
849                         }
850                         add_ima(2, simasel, direntry);
851                         ima_added = 1;
852                 }
853                 direntry = direntry->next;
854         }
855         
856         imsort(&simasel->first_sel_ima);
857         
858         simasel->fase |= IMS_KNOW_BIP;
859         simasel->fase |= IMS_KNOW_INF;
860         simasel->fase |= IMS_KNOW_IMA;
861         
862         if (ima_added){
863                 simasel->fase |= IMS_DOTHE_IMA;
864                 simasel->fase &= ~IMS_KNOW_IMA;
865                 addafterqueue(curarea->win, AFTERIMASELGET, 1);
866         }else{
867                 write_new_pib(simasel);
868         }               
869         
870         waitcursor(0);
871 }
872
873 void change_imadir(SpaceImaSel *simasel)
874 {
875         ImaDir  *direntry;
876         int i;
877         
878         direntry = simasel->firstdir; 
879         for (i=0; i<simasel->hilite; i++){
880                 direntry = direntry->next;      
881         }
882         
883         if(direntry==NULL);
884         else if (direntry->name[0] != '.'){
885                 strcat(simasel->dir, direntry->name);
886                 strcat(simasel->dir, "/");
887         }
888         else {
889                 if (direntry->name[1] == '.'){
890                         imadir_parent(simasel); 
891                 }
892         }
893         
894         clear_ima_dir(simasel);
895 }
896
897 void check_imasel_copy(SpaceImaSel *simasel)
898 {
899
900         /* WATCH IT: also used when reading blender file */
901         /* initialize stuff, malloc, etc */
902         simasel->first_sel_ima  =  0;
903         simasel->hilite_ima         =  0;
904         simasel->firstdir               =  0;
905         simasel->firstfile              =  0;
906         simasel->cmap           =  0;
907         clear_ima_dir(simasel);
908         
909         // simasel->cmap= IMB_loadiffmem((int*)datatoc_cmap_tga, IB_rect|IB_cmap);
910         simasel->cmap= IMB_ibImageFromMemory((int *)datatoc_cmap_tga, datatoc_cmap_tga_size, IB_rect|IB_cmap);
911 }
912
913 void free_imasel(SpaceImaSel *simasel)
914 {
915         /* do not free imasel itself */
916         
917         clear_ima_dir(simasel);
918         IMB_freeImBuf(simasel->cmap);
919 }
920