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