Bringing vpdf from vendor/MorphOS-OSS/current into main branch.
[AROS-Contrib.git] / vpdf / system / file.c
blob9f2d339075c908d6fa10187494c16d302565d3dc
1 /*
3 File reading/writing functions. (done)
4 Image loading (via datatypes) (done).
5 Chunky Image loading. (done)
6 Texture loading (automatical scaling).
8 Implemented better error handling.
9 If picture is not found it is replaced by blank image and black palette.
10 If any function fails to allocate memory then program exits automaticaly.
12 v1.1
13 Forget to free temporary ARGB buffer in 16bit loading.
14 v1.2
15 Improved error handling a bit.
16 Texture filename is preserved (for texture caching?)
17 v1.3
18 Added some error handling into JPEG loading code
19 Added some speed optimizations (50% in DT loader!)
20 Fixed some bugs after optimizations.
21 v1.4
22 Removed some obsolete functions (8bit support mainly)
24 v2.0
25 Cleaned up the code. Fixed 32bit DT loader and some other loading functions.
26 Also some textures haven't got the name assigned.
27 v2.1
28 Added PNG support.
29 Moved some stuff into other files.
34 #include <stdlib.h>
35 #include <string.h>
37 #include <dos/dos.h>
38 #include <exec/memory.h>
40 #include <proto/alib.h>
41 #include <proto/dos.h>
42 #include <proto/graphics.h>
43 #define USE_INLINE_STDARG
44 #include <proto/multimedia.h>
45 #include <classes/multimedia/video.h>
46 #undef USE_INLINE_STDARG
48 #include <utility/tagitem.h>
49 #define SYSTEM_PRIVATE
50 #include <intuition/extensions.h>
52 #include <datatypes/pictureclass.h>
53 #include <intuition/gadgetclass.h>
55 #include <proto/datatypes.h>
56 #include <proto/dtclass.h>
57 #include <proto/muimaster.h>
59 #include <cybergraphx/cybergraphics.h>
61 #include <emul/emulregs.h>
62 #include <emul/emulinterface.h>
64 #include "chunky.h"
65 #include "file.h"
66 #include "data.h"
67 #include "functions.h"
68 #include "timer.h"
69 #include "loadsunrast.h"
70 #include "loadpng.h"
71 #include "memory.h"
72 #include "string.h"
73 #include "util.h"
75 static int debugmode = 0;
77 static char *lastFileType = NULL;
78 static void setLastFileType(char *type);
80 struct Library *DataTypesBase;
82 void dprintf(char *fmt, ...);
84 void SetDebugMode(int mode)
86 debugmode = mode;
89 //#define ENABLE_16BIT
91 /// loadfile()
93 void *fileLoad(char *name)
95 return dataLoadFile(name);
98 void fileFree(void *file)
100 free(file);
103 ////
105 /// fileGetFilePart()
107 char *fileGetFilePart(char *fname)
109 if (fname != NULL)
110 return FilePart(fname);
111 else
112 return NULL;
115 ////
117 /// savefile()
119 int savefile(char *name, void *mem, int len)
121 FILE *file;
123 file = fopen(name, "w");
124 if (file == NULL)
126 printf("Could not open file for writing:%s!\n", name);
127 return FALSE;
130 fwrite(mem, len, 1, file);
131 fclose(file);
132 return TRUE;
135 ////
137 /// filelen()
139 unsigned int fileLength(char *fname)
141 unsigned int l = dataFileLength(fname);
142 return l;
144 ////
146 /// AllocTexture
148 Texture *AllocTextureStruct(void)
150 return (Texture*)calloc(1, sizeof(Texture));
153 ////
155 /// FreeTexture()
157 void FreeTexture(Texture *txt)
159 if (txt != NULL)
161 chkFree(txt->image);
162 txt->image = NULL;
163 free(txt->name);
164 free(txt->alphaname);
165 free(txt->type);
166 free(txt);
170 ////
172 /// txt_CreateBlank8()
174 Texture *txt_CreateBlank(int width, int height)
176 return txtCreateBlank(width, height, CHK_PIXFMT_LUT);
179 ////
181 /// txt_CreateBlank16()
182 #ifdef ENABLE_16BIT
183 Texture *txt_CreateBlank16(int width, int height)
185 return txtCreateBlank(width, height, CHK_PIXFMT_RGB565);
187 #endif
188 ////
190 /// txt_CreateBlank24()
192 Texture *txt_CreateBlank24(int width, int height)
194 return txtCreateBlank(width, height, CHK_PIXFMT_RGB888);
197 ////
199 /// txt_CreateBlank32()
201 Texture *txt_CreateBlank32(int width, int height)
203 return txtCreateBlank(width, height, CHK_PIXFMT_ARGB8888);
205 ////
207 /// txtCreate(width, height, format)
209 Texture *txtCreate(int width, int height, int pixfmt)
211 Texture *txt = AllocTextureStruct();
213 if (txt != NULL)
215 txt->image = chkCreate(width, height, pixfmt, FALSE);
217 if (txt->image != NULL)
219 /* make sure that pixel format is set correctly */
221 txt->image->pixfmt = pixfmt;
223 else
225 txtFree(txt);
226 txt = NULL;
230 return txt;
233 ////
235 /// txtCreateFromImage(ChkImage)
237 Texture *txtCreateFromImage(ChkImage *image)
239 Texture *txt = AllocTextureStruct();
241 if (txt != NULL)
242 txt->image = image;
244 return txt;
247 ////
249 /// txtCreateBlank(width, height, format)
251 Texture *txtCreateBlank(int width, int height, int pixfmt)
253 Texture *txt = txtCreate(width, height, pixfmt);
255 if (txt)
257 memset(txt->image->data.p, 0, width * height * fmtGetBytesPerPixel(pixfmt));
260 return txt;
263 ////
265 /// static LoadDTPicture()
267 static Texture *LoadDTPicture(char *fname, int chkpixfmt)
269 Object *dt_object;
270 unsigned int *cregs, numcols;
271 struct BitMapHeader *bmhd;
272 struct BitMap *bitmap;
273 struct pdtBlitPixelArray pdtmsg;
274 Texture *txt = NULL;
275 int alpha;
277 //__timerGlobalStart();
279 if (chkpixfmt !=CHK_PIXFMT_ARGB8888 && chkpixfmt != CHK_PIXFMT_RGB888)
280 return NULL;
282 if (fname != NULL)
284 //printf("newdtobject:%s\n", fname);
285 //printf("%d\n", AvailMem(MEMF_ANY));
286 dt_object = NewDTObject (fname,
287 DTA_GroupID, GID_PICTURE,
288 PDTA_DestMode, PMODE_V43,
289 PDTA_Remap, FALSE,
290 PDTA_Displayable, FALSE,
291 TAG_DONE);
293 //printf("dto:%d. freemem: %d\n", dt_object, AvailMem(MEMF_ANY));
295 else
297 dt_object = NewDTObject (0,
298 DTA_GroupID, GID_PICTURE,
299 DTA_SourceType, DTST_CLIPBOARD,
300 PDTA_DestMode, PMODE_V43,
301 PDTA_Remap, FALSE,
302 PDTA_Displayable, FALSE,
303 TAG_DONE);
305 if (dt_object == NULL)
306 printf("Failed!\n");
309 if (dt_object == NULL)
311 //printf("not enough memory\n");
312 return NULL;
316 int result;
317 struct TagItem tags[] =
319 {PDTA_CRegs, (unsigned int) &cregs},
320 {PDTA_NumColors, (unsigned int) &numcols},
321 {PDTA_BitMapHeader, (unsigned int) &bmhd},
322 {PDTA_BitMap, (unsigned int) &bitmap},
323 {PDTA_AlphaChannel, (unsigned int) &alpha},
324 {0, 0}
327 result = GetDTAttrsA(dt_object, tags);
329 if (result != 5)
331 printf("[FILE]: Error in datatype\n");
332 DisposeDTObject(dt_object);
333 return NULL;
337 //printf("time:%f\n",__timerGlobalGet(1.0f));
338 //__timerGlobalStart();
341 /* get datatype */
344 struct DataType *dt = NULL;
346 if (GetDTAttrs(dt_object, DTA_DataType, (unsigned int)&dt, TAG_DONE))
348 if (dt != NULL)
350 char *name_string = dt->dtn_Header->dth_Name;
351 setLastFileType(name_string);
354 else
356 setLastFileType("Unknown");
360 txt = txtCreate(bmhd->bmh_Width, bmhd->bmh_Height, chkpixfmt);
362 //printf("time2:%f\n",__timerGlobalGet(1.0f));
363 //__timerGlobalStart();
365 if (txt == NULL)
367 //printf("[FILE]: Can't allocate buffer\n");
368 DisposeDTObject(dt_object);
369 return NULL;
372 if (bmhd->bmh_Depth <= 8) // remap image to 24bit
374 struct RastPort rastport, temprastport;
375 struct BitMap *tempbitmap;
376 unsigned char *target, *colormap;
377 unsigned char *penarray;
378 int i, x, y;
380 tempbitmap = AllocBitMap(bmhd->bmh_Width, 1, bmhd->bmh_Depth, BMF_CLEAR, NULL);
381 if (!tempbitmap)
383 printf("[FILE]: Can't allocate temporary bitmap\n");
384 DisposeDTObject(dt_object);
385 FreeTexture(txt);
386 return NULL;
389 colormap = calloc(numcols, 3);
390 for (i = 0; i < numcols; i++)
392 colormap[ i * 3 + 0 ] = cregs[ 3 * i + 0 ] >> 24;
393 colormap[ i * 3 + 1 ] = cregs[ 3 * i + 1 ] >> 24;
394 colormap[ i * 3 + 2 ] = cregs[ 3 * i + 2 ] >> 24;
397 InitRastPort(&rastport);
398 rastport.BitMap = bitmap;
399 InitRastPort(&temprastport);
400 temprastport.BitMap = tempbitmap;
401 penarray = calloc(1, ((bmhd->bmh_Width + 15) >> 4) << 4);
403 target = txt->image->data.b;
404 for (y = 0; y < bmhd->bmh_Height; y++)
406 ReadPixelLine8(&rastport, 0, y, bmhd->bmh_Width, penarray, &temprastport);
408 if (chkpixfmt == CHK_PIXFMT_ARGB8888)
410 for (x = 0; x < bmhd->bmh_Width; x++)
412 *target++ = 0xff;
413 *target++ = colormap[ penarray[ x ] * 3 ];
414 *target++ = colormap[ penarray[ x ] * 3 + 1 ];
415 *target++ = colormap[ penarray[ x ] * 3 + 2 ];
418 else if (chkpixfmt == CHK_PIXFMT_RGB888)
420 for (x = 0; x < bmhd->bmh_Width; x++)
422 *target++ = colormap[ penarray[ x ] * 3 ];
423 *target++ = colormap[ penarray[ x ] * 3 + 1 ];
424 *target++ = colormap[ penarray[ x ] * 3 + 2 ];
429 free(colormap);
430 free(penarray);
431 FreeBitMap(tempbitmap);
434 else if ( bmhd->bmh_Depth == 24 && alpha == 0)
436 #if 1
437 int i;
439 for (i=0;i<txt->image->height;i++)
441 unsigned char *dst;
443 if (chkpixfmt == CHK_PIXFMT_ARGB8888)
444 dst = txt->image->data.b + i * bmhd->bmh_Width * 4;
445 else
446 dst = txt->image->data.b + i * bmhd->bmh_Width * 3;
448 pdtmsg.MethodID = PDTM_READPIXELARRAY;
449 pdtmsg.pbpa_PixelData = dst;
450 pdtmsg.pbpa_PixelFormat = chkpixfmt == CHK_PIXFMT_ARGB8888 ? PBPAFMT_ARGB : PBPAFMT_RGB;
451 pdtmsg.pbpa_PixelArrayMod = bmhd->bmh_Width * 3;
452 pdtmsg.pbpa_Left = 0;
453 pdtmsg.pbpa_Top = i;
454 pdtmsg.pbpa_Width = bmhd->bmh_Width;
455 pdtmsg.pbpa_Height = 1;
457 DoMethodA(dt_object, (Msg)&pdtmsg);
459 /* this method for RGB images sets alpha to 0. We need to set it to 0xff */
461 if (chkpixfmt == CHK_PIXFMT_ARGB8888)
462 convertARGB0888_to_ARGB8888(dst, dst, txt->image->width, 1);
465 #else
467 __timerGlobalStart();
469 pdtmsg.MethodID = PDTM_READPIXELARRAY;
470 pdtmsg.pbpa_PixelData = txt->image->data.p;
471 pdtmsg.pbpa_PixelFormat = PBPAFMT_RGB;
472 pdtmsg.pbpa_PixelArrayMod = bmhd->bmh_Width * 3;
473 pdtmsg.pbpa_Left = 0;
474 pdtmsg.pbpa_Top = 0;
475 pdtmsg.pbpa_Width = bmhd->bmh_Width;
476 pdtmsg.pbpa_Height = bmhd->bmh_Height;
478 DoDTMethodA(dt_object, (Msg) & pdtmsg);
479 //printf("time3.1:%f\n",__timerGlobalGet(1.0f));
480 //__timerGlobalStart();
481 //expandRGB888_to_ARGB8888(txt->image->data.p, txt->image->data.p, txt->image->width, txt->image->height);
482 //printf("time3.2:%f\n",__timerGlobalGet(1.0f));
484 #endif
487 else
489 pdtmsg.MethodID = PDTM_READPIXELARRAY;
490 pdtmsg.pbpa_PixelData = txt->image->data.p;
491 pdtmsg.pbpa_PixelFormat = chkpixfmt == CHK_PIXFMT_ARGB8888 ? PBPAFMT_ARGB : PBPAFMT_RGB;
492 pdtmsg.pbpa_PixelArrayMod = bmhd->bmh_Width * (chkpixfmt == CHK_PIXFMT_ARGB8888 ? 4 : 3);
493 pdtmsg.pbpa_Left = 0;
494 pdtmsg.pbpa_Top = 0;
495 pdtmsg.pbpa_Width = bmhd->bmh_Width;
496 pdtmsg.pbpa_Height = bmhd->bmh_Height;
498 DoMethodA(dt_object, (Msg)&pdtmsg);
501 //printf("time3:%f\n",__timerGlobalGet(1.0f));
502 //__timerGlobalStart();
503 DisposeDTObject(dt_object);
504 //printf("time4:%f\n",__timerGlobalGet(1.0f));
505 return txt;
508 ////
510 /// static LoadDTPictureTRUE24()
512 static Texture *LoadDTPictureTRUE24(char *fname)
514 return LoadDTPicture(fname, CHK_PIXFMT_RGB888);
516 ////
518 /// static LoadDTPictureTRUE32()
520 static Texture *LoadDTPictureTRUE32(char *fname)
522 return LoadDTPicture(fname, CHK_PIXFMT_ARGB8888);
524 ////
526 /// static LoadReggaePictureTRUE32()
528 static Texture *LoadReggaePicture(char *fname, int chkpixfmt)
530 Texture *txt = NULL;
531 APTR fileobj = MultimediaBase != NULL ? MediaNewObjectTags(
532 MMA_StreamName, (IPTR)fname,
533 MMA_StreamType, (IPTR)"file.stream",
534 MMA_MediaType, MMT_PICTURE,
535 TAG_DONE) : NULL;
537 if (fileobj != NULL)
539 ULONG pics;
541 pics = xget(fileobj, MMA_Ports);
543 if (pics)
545 int width = MediaGetPort(fileobj, 0, MMA_Video_Width);
546 int height = MediaGetPort(fileobj, 0, MMA_Video_Height);
548 if (width > 0 && height > 0)
550 txt = txtCreate(width, height, chkpixfmt);
552 if (txt != NULL)
555 if (chkpixfmt == CHK_PIXFMT_ARGB8888)
556 DoMethod(fileobj, MMM_Pull, 0, txt->image->data.p, width * height * 4);
557 else
559 unsigned char *buffer = mmalloc(width * 4);
560 int i;
562 if (buffer != NULL)
564 for(i=0; i<height; i++)
566 DoMethod(fileobj, MMM_Pull, 0, buffer, width * 4);
567 convertRGB888_to_ARGB8888(buffer, txt->image->data.b + width * 3 * i, width, 1);
570 mfree(buffer);
577 DisposeObject(fileobj);
580 return txt;
583 ////
585 /// fileGetType()
587 void fileGetType(char *fname, char *type)
589 /* get datatype */
591 BPTR lock = Lock(fname, ACCESS_READ);
593 strcpy(type, "Unknown");
595 if (lock != NULL)
597 /* check if it's recognizable by datatypes */
599 struct DataType *dt = ObtainDataTypeA(DTST_FILE, (APTR)lock, NULL);
601 if (dt != NULL)
603 char *name_string = dt->dtn_Header->dth_Name;
605 strcpy(type, name_string);
607 if (!stricmp(type, "JFIF"))
608 strcpy(type, "JPEG");
610 ReleaseDataType(dt);
613 UnLock(lock);
616 ////
618 /// fileGetInfo()/fileFreeInfo()
620 FileInfo *fileGetInfo(char *fname, int flags)
622 FileInfo *finfo;
624 finfo = calloc(1, sizeof(FileInfo));
626 if (finfo != NULL)
628 /* get datatype */
630 BPTR lock = Lock(fname, ACCESS_READ);
632 if (lock != NULL)
634 struct DataType *dt = NULL;
635 APTR fileobj = NULL;
637 /* check if it's recognizable by datatypes */
639 if (flags & FINFO_DATATYPE)
640 dt = ObtainDataTypeA(DTST_FILE, (APTR)lock, NULL);
642 if (dt != NULL)
644 char *name_string = dt->dtn_Header->dth_Name;
646 finfo->type = strdup(name_string);
647 if (finfo->type && !stricmp(finfo->type, "JFIF"))
648 strcpy(finfo->type, "JPEG");
650 finfo->gid = dt->dtn_Header->dth_GroupID;
652 ReleaseDataType(dt);
654 else if (MultimediaBase != NULL) /* check if recognized by reggae */
656 fileobj = MediaNewObjectTags(
657 MMA_StreamName, (IPTR)fname,
658 MMA_StreamType, (IPTR)"file.stream",
659 MMA_MediaType, MMT_PICTURE,
660 TAG_DONE);
662 if (fileobj != NULL)
664 ULONG pics = xget(fileobj, MMA_Ports);
666 if (pics)
668 char *type = (char*)MediaGetPort(fileobj, 0, MMA_DataFormat);
669 if (type != NULL)
670 finfo->type = strdup(type);
672 finfo->gid = GID_PICTURE;
674 else
676 DisposeObject(fileobj);
677 fileobj = NULL;
682 if (finfo->type == NULL)
684 finfo->type = strdup("Unknown");
687 /* get dimmensions */
689 if (flags & FINFO_DIMMENSIONS)
691 int success = pngGetDimmensions(fname, &finfo->width, &finfo->height);
692 if (success == FALSE)
693 success = jpegGetDimmensions(fname, &finfo->width, &finfo->height);
694 if (success == FALSE)
696 Object *dt_object = NewDTObject (fname,
697 DTA_GroupID, GID_PICTURE,
698 PDTA_DestMode, PMODE_V43,
699 PDTA_Remap, FALSE,
700 PDTA_Displayable, FALSE,
701 TAG_DONE);
703 if (dt_object != NULL)
705 struct BitMapHeader *bmhd;
706 struct TagItem tags[] =
708 {PDTA_BitMapHeader, (unsigned int) &bmhd},
709 {TAG_DONE}
712 int result = GetDTAttrsA(dt_object, tags);
714 if (result == 1)
716 finfo->width = bmhd->bmh_Width;
717 finfo->height = bmhd->bmh_Height;
718 success = TRUE;
721 DisposeDTObject(dt_object);
724 if (success == FALSE)
726 if (fileobj != NULL)
728 finfo->width = MediaGetPort(fileobj, 0, MMA_Video_Width);
729 finfo->height = MediaGetPort(fileobj, 0, MMA_Video_Height);
734 if (fileobj != NULL)
735 DisposeObject(fileobj);
737 /* get other file properties (timestamp. size) */
740 struct FileInfoBlock fib;
742 if (Examine(lock, &fib))
744 finfo->datestamp = fib.fib_Date;
745 finfo->filesize = fib.fib_Size;
749 else
751 free(finfo);
752 finfo = NULL;
755 UnLock( lock );
758 return finfo;
761 void fileFreeInfo(FileInfo *finfo)
763 if (finfo != NULL)
765 free(finfo->type);
766 free(finfo);
770 ////
772 /// LoadPictureHI16()
773 #ifdef ENABLE_16BIT
774 Texture *LoadPictureHI16(char *fname)
776 Texture *txt = NULL;
778 /* try to load using JPEG loader */
779 if (stricmp(fname + strlen(fname) - 4, ".jpg") == 0)
781 txt = LoadPictureJPEG(fname);
784 if (!txt)
786 if (!txt)
787 txt = LoadDTPictureTRUE24(fname);
789 if (txt)
791 /* convert image into 16bit RGB */
792 Texture *nTxt = txtCreate(txt->image->width, txt->image->height, CHK_PIXFMT_RGB565);
793 if (!nTxt)
795 FreeTexture(txt);
796 txt = NULL;
798 else
800 convertRGB888_to_RGB565(txt->image->data.p, nTxt->image->data.p, txt->image->width, txt->image->height);
801 FreeTexture(txt);
802 txt = nTxt;
807 if (!txt)
809 //printf("[File]: Failed to load image: %s\n", fname);
810 return NULL;
813 txt->name = strduplicate(fname);
815 return txt;
817 #endif
818 ////
820 /// LoadPictureTRUE24()
822 Texture *LoadPictureTRUE24(char *fname)
824 Texture *txt = NULL;
825 int len;
827 if (fname == NULL)
829 /* load from clipboard */
831 txt = LoadDTPictureTRUE32(NULL);
833 if (!txt)
834 return NULL;
836 txt->name = strduplicate("Clipboard");
838 return txt;
841 len = strlen(fname);
842 #if 1
843 /* try to load using JPEG loader */
844 if (stricmp(fname + len - 4, ".jpg") == 0)
846 txt = LoadPictureJPEG24(fname);
847 setLastFileType("JPEG");
850 if ((!txt) && len > 4 && (stricmp(fname + len - 4, ".ras") == 0))
852 txt = SUNLoadPicture24(fname);
853 setLastFileType("Sun Raster");
855 if ((!txt) && len > 6 && (stricmp(fname + len - 6, ".ras24") == 0))
857 txt = SUNLoadPicture24(fname);
858 setLastFileType("Sun Raster");
860 if ((!txt) && len > 6 && (stricmp(fname + len - 6, ".ras32") == 0))
862 txt = SUNLoadPicture24(fname);
863 setLastFileType("Sun Raster");
865 #endif
866 if (!txt)
868 txt = LoadDTPictureTRUE24(fname);
871 if (txt == NULL)
873 //printf("[File]: Failed to load image: %s\n", fname);
874 return NULL;
877 txt->name = strduplicate(fname);
878 txt->type = strDuplicate(getLastFileType());
880 return txt;
883 ////
885 /// LoadPictureGRAY8()
887 Texture *LoadPictureGRAY8(char *fname)
889 Texture *txt = NULL;
891 /* try to load using JPEG loader */
892 if (stricmp(fname + strlen(fname) - 4, ".jpg") == 0)
894 txt = LoadPictureJPEG8(fname);
897 if (!txt)
899 /* load using DT */
901 if (!txt)
902 txt = LoadDTPictureTRUE24(fname);
904 if (txt)
906 /* convert image into 8bit LUMINANCE */
907 Texture *nTxt = txtCreate(txt->image->width, txt->image->height, CHK_PIXFMT_LUMINANCE);
908 if (!nTxt)
910 FreeTexture(txt);
911 txt = NULL;
913 else
915 convertRGB888_to_L8(txt->image->data.p, nTxt->image->data.p, txt->image->width, txt->image->height);
916 FreeTexture(txt);
917 txt = nTxt;
922 if (!txt)
924 //printf("[File]: Failed to load image: %s\n", fname);
925 return NULL;
928 txt->name = strduplicate(fname);
930 return txt;
933 ////
935 /// LoadPictureTRUE32()
937 Texture *LoadPictureTRUE32(char *fname)
939 return LoadPictureARGB32(fname);
942 ////
944 /// LoadPictureARGB16()
946 #ifdef ENABLE_16BIT
947 Texture *LoadPictureARGB16(char *fname)
949 Texture *txt = NULL;
951 /* try to load using JPEG loader */
952 if (stricmp(fname + strlen(fname) - 4, ".jpg") == 0)
954 txt = LoadPictureJPEG32(fname);
957 if (!txt)
958 txt = LoadDTPictureTRUE32(fname);
960 /* convert into 16bit ARGB */
962 if (txt)
964 Texture *nTxt = txtCreate(txt->image->width, txt->image->height, CHK_PIXFMT_ARGB4444);
965 if (!nTxt)
967 FreeTexture(txt);
968 txt = NULL;
970 else
972 convertARGB8888_to_ARGB4444(txt->image->data.p, nTxt->image->data.p, txt->image->width, txt->image->height);
973 FreeTexture(txt);
974 txt = nTxt;
978 if (!txt)
980 //printf("[File]: Failed to load image: %s\n", fname);
981 return NULL;
984 txt->name = strduplicate(fname);
986 return txt;
988 #endif
989 ////
991 /// LoadPictureARGB32()
993 Texture *LoadPictureARGB32(char *fname)
995 Texture *txt = NULL;
996 int len;
998 if (fname == NULL)
1000 /* load from clipboard */
1002 txt = LoadDTPictureTRUE32(NULL);
1004 if (txt == NULL)
1005 return NULL;
1007 txt->name = strduplicate("Clipboard");
1008 return txt;
1011 len = strlen(fname);
1013 #if 1
1014 /* try to load using JPEG loader */
1015 if (stricmp(fname + len - 4, ".jpg") == 0)
1017 //__timerGlobalStart();
1018 txt = LoadPictureJPEG32(fname);
1019 setLastFileType("JPEG");
1021 //printf("time:%f\n",__timerGlobalGet(1.0f));
1024 if ((!txt) && len > 4 && (stricmp(fname + len - 4, ".ras") == 0))
1026 txt = SUNLoadPicture32(fname);
1027 setLastFileType("Sun Raster");
1029 if ((!txt) && len > 6 && (stricmp(fname + len - 6, ".ras24") == 0))
1031 txt = SUNLoadPicture32(fname);
1032 setLastFileType("Sun Raster");
1034 if ((!txt) && len > 6 && (stricmp(fname + len - 6, ".ras32") == 0))
1036 txt = SUNLoadPicture32(fname);
1037 setLastFileType("Sun Raster");
1039 #endif
1040 if (txt == NULL)
1041 txt = LoadDTPictureTRUE32(fname);
1043 if (txt == NULL)
1044 txt = LoadReggaePicture(fname, CHK_PIXFMT_ARGB8888);
1046 if (txt == NULL)
1048 //printf("[File]: Failed to load image: %s\n", fname);
1049 return NULL;
1052 txt->name = strduplicate(fname);
1053 txt->type = strDuplicate(getLastFileType());
1055 return txt;
1058 ////
1060 /// isDTPicture()
1062 #include "timer.h"
1064 int isDTPicture(char *fname)
1067 #if 1
1068 //__timerGlobalStart();
1071 int isPicture = 0;
1072 BPTR lock = Lock(fname, ACCESS_READ);
1074 if (lock)
1076 /* check if it's recognizable by datatypes */
1078 struct DataType *dt = ObtainDataType(DTST_FILE, (APTR)lock, DTA_GroupID, GID_PICTURE, NULL);
1080 if (dt != NULL)
1082 /* check if it's a picture (should always be, but well) */
1084 if (dt->dtn_Header->dth_GroupID == GID_PICTURE)
1085 isPicture = 1;
1087 ReleaseDataType(dt);
1090 UnLock(lock);
1092 /* check if recognized by reggae */
1094 if (isPicture == FALSE)
1096 APTR fileobj = MultimediaBase != NULL ? MediaNewObjectTags(
1097 MMA_StreamName, (IPTR)fname,
1098 MMA_StreamType, (IPTR)"file.stream",
1099 MMA_MediaType, MMT_PICTURE,
1100 TAG_DONE) : NULL;
1102 if (fileobj != NULL)
1104 isPicture = 1;
1105 DisposeObject(fileobj);
1110 /* check for builtin image formats */
1113 static char *suffixes[] = {
1114 ".ras",
1115 ".ras32",
1116 ".ras24",
1119 int num = 3;
1120 int len = strlen(fname);
1121 int i;
1123 for (i=0;i<num;i++)
1125 int slen = strlen(suffixes[ i ]);
1126 if (slen <= len)
1128 if (0 == stricmp(suffixes[ i ], &fname[ len - slen ]))
1130 isPicture = 1;
1136 //printf("Time of analysis:%f\n",__timerGlobalGet(1.0f));
1138 return isPicture;
1141 #else
1143 /* Fast recognition method. Not too accurate though */
1146 static char *suffixes[] = {
1147 ".jpg",
1148 ".png",
1149 ".iff",
1150 ".iff24",
1151 ".gif",
1152 ".pcx",
1153 ".ppm",
1154 ".info",
1155 ".ras",
1156 ".ras32",
1157 ".ras24",
1158 ".ilbm",
1159 ".bmp",
1160 ".mim",
1161 ".mf1",
1162 ".mf0",
1163 ".mbr",
1164 ".jpeg"
1167 int num = 18;
1168 int len = strlen(fname);
1169 int i;
1171 for (i=0;i<num;i++)
1173 int slen = strlen(suffixes[ i ]);
1174 if (slen <= len)
1176 if (0 == stricmp(suffixes[ i ], &fname[ len - slen ]))
1178 return 1;
1183 return 0;
1186 #endif
1189 ////
1191 /// checkExtension()
1193 int checkExtension(char *fname, char *extension)
1195 int len = strlen(fname);
1196 int slen = strlen(extension);
1198 if (slen <= len)
1200 if (0 == stricmp(extension, &fname[len - slen]))
1201 return 1;
1204 return 0;
1207 ////
1209 /// dirDelete()
1211 void dirDelete(char *path, int recursive)
1213 /* lock the dir */
1215 BPTR dirLock = Lock(path, ACCESS_READ);
1216 struct FileInfoBlock fib;
1218 if (!dirLock)
1219 return;
1221 if (dirLock)
1223 if (Examine(dirLock, &fib))
1225 if (isDir(&fib))
1227 /* fine. we can start examining the entries */
1229 while(ExNext(dirLock, &fib))
1231 /* build new path */
1233 int buffSize = strlen(path) + strlen(fib.fib_FileName) + 2;
1234 char *newPath = calloc(1, buffSize);
1236 if (path)
1238 strcpy(newPath, path);
1239 AddPart(newPath, fib.fib_FileName, buffSize);
1241 /* check type of an entry */
1243 if (isDir(&fib) && recursive)
1245 /* call ourself for this new directory */
1247 dirDelete(newPath, recursive);
1249 else
1251 DeleteFile(newPath);
1254 free(newPath);
1256 else
1258 printf("Not enough memory for path(%d bytes)\n",buffSize);
1264 UnLock(dirLock);
1267 DeleteFile(path);
1268 return;
1271 ////
1273 /// fileDelete()
1275 int fileDelete(char *file)
1277 return DeleteFile(file);
1280 ////
1282 /// fileCopyTo()
1284 int fileCopyTo(char *src, char *dst)
1286 char *buf;
1288 if (!src || !dst)
1289 return 0;
1291 /* check if they are equal first */
1293 if (pathEquals(src, dst))
1295 return 1;
1298 /* */
1300 buf = (char*)malloc(65536);
1302 if (buf != NULL)
1304 BPTR f1 = Open(src, MODE_OLDFILE);
1305 BPTR f2 = NULL;
1307 if (f1 == NULL)
1309 SetIoErr(ERROR_OBJECT_NOT_FOUND);
1310 free(buf);
1311 return 0;
1314 f2 = Open(dst, MODE_NEWFILE);
1316 if (f1 && f2)
1318 int len = fileLength(src);
1320 if (len != SetFileSize(f2, len, OFFSET_BEGINING))
1322 /* not enough space on the device */
1324 Close(f1);
1325 Close(f2);
1326 free(buf);
1327 DeleteFile(dst);
1328 return 0;
1331 Seek(f2, 0, OFFSET_BEGINING);
1333 while(len)
1335 int bytesw = 0;
1336 int bytesr = Read(f1, buf, min(len, 65536));
1338 if (bytesr != min(len, 65536))
1340 /* read error */
1342 Close(f1);
1343 Close(f2);
1344 DeleteFile(dst);
1345 free(buf);
1346 return 0;
1349 bytesw = Write(f2, buf, min(len, 65536));
1351 if (bytesr != bytesw)
1353 /* write error */
1355 Close(f1);
1356 Close(f2);
1357 DeleteFile(dst);
1358 free(buf);
1359 return 0;
1362 len -= min(len, 65536);
1365 Close(f1);
1366 Close(f2);
1367 free(buf);
1368 return 1;
1370 else
1372 /* failed to open file for read or write */
1374 if (f1)
1375 Close(f1);
1376 if (f2)
1377 Close(f2);
1379 free(buf);
1381 return 0;
1384 ////
1386 /// filesCopy()
1389 * This one kind of doesn't fit here, but well....
1392 int filesCopy(Object *app, char *reqtitle, char **list, char *dest, int move)
1394 int error = 0;
1395 int selected = 0;
1397 while(list[selected] != NULL)
1399 selected++;
1402 /* get destination */
1405 int num = selected;
1406 int i;
1407 int forall = 0;
1409 /* process each name */
1411 for(i=0; i<num; i++)
1413 char *name = list[ i ];
1415 /* add path to dest */
1417 char *newdest = strAddFilePart(dest, FilePart(name));
1418 char *path = name;
1420 /* mode for file */
1422 int skip = 0;
1424 if (forall != 2 && newdest) /* forall == 2 -> about, but we move through all anyway */
1426 /* check if file exists */
1428 if (fileLength(newdest))
1430 if (forall == 1) /* replace */
1431 skip = 0;
1432 else if (forall == -1)/* skip */
1433 skip = 1;
1434 else
1436 /* file exists. display req */
1437 int res;
1439 if (selected > 1)
1441 res = MUI_Request(app, NULL, 0, reqtitle, "*_Replace|Replace _All|_Skip|S_kip All|Abort ",
1442 "Destination file \33b%s \33nalready exists", FilePart(path),
1443 TAG_END);
1445 switch (res)
1447 case 2: /* replace all */
1448 forall = 1;
1449 case 1: /* fall through to replace */
1450 skip = 0;
1451 break;
1452 case 4: /* skip all */
1453 forall = -1;
1454 case 3: /* fall through to skip */
1455 skip = 1;
1456 break;
1457 case 0: /* abort */
1458 forall = 2;
1459 skip = 1;
1462 else
1464 res = MUI_Request(app, NULL, 0, reqtitle, "*_Replace|Abort ",
1465 "Destination file \33b%s \33nalready exists", FilePart(newdest),
1466 TAG_END);
1467 switch (res)
1469 case 1: /* replace all */
1470 forall = 1;
1471 break;
1472 case 0: /* skip all */
1473 forall = 2;
1474 skip = 1;
1480 /* copy */
1482 if (!skip)
1484 if (!fileCopyTo(path, newdest))
1486 /* error */
1488 char msg[128];
1490 Fault(IoErr(), "", msg, sizeof(msg));
1492 MUI_Request(app, NULL, 0, "ShowGirls ยท Error...", "OK",
1493 "Failed to copy file:\n\n\033b%s\033n to\n\033b%s\033n\n\nError message %s", path, dest, msg,
1494 TAG_END);
1495 error = 1;
1497 else
1499 /* if "move" mode then delete file */
1501 if (move)
1502 fileDelete(path);
1506 /* free singlefile paths */
1508 free(newdest);
1512 return error;
1515 ////
1517 char *getLastFileType(void)
1519 return lastFileType ? lastFileType : "";
1522 /// pathEquals()
1524 int pathEquals(char *p1, char *p2)
1526 BPTR l1 = Lock(p1, ACCESS_READ);
1527 BPTR l2 = Lock(p2, ACCESS_READ);
1528 char path1[1024];
1529 char path2[1024];
1530 int rc = FALSE;
1532 if (l1 == NULL || l2 == NULL)
1535 else
1537 if (NameFromLock(l1, path1, sizeof(path1)) && NameFromLock(l2,path2,sizeof(path2)))
1539 if (strcmp(path1, path2) == 0)
1540 rc = TRUE;
1544 UnLock(l1);
1545 UnLock(l2);
1547 return rc;
1550 ////
1552 static void setLastFileType(char *type)
1554 free(lastFileType);
1556 lastFileType = strdup(type);
1557 if (lastFileType && !stricmp(lastFileType, "JFIF"))
1558 strcpy(lastFileType, "JPEG");
1561 /// fileFormatString()
1563 void fileFormatString(char *str, int n, char *fname)
1566 ////
1568 /// CapacityFormat() - capacity formatter
1570 char *CapacityFormat(char *s, unsigned int size, unsigned long long n)
1572 if (n < 1024 * 10)
1573 snprintf(s, size, "%u bytes", (unsigned int)n);
1574 else if (n < 1024 * 1024)
1575 snprintf(s, size, "%u.%u KB", (unsigned int) (n / 1024), (unsigned int)(n % 1024 * 10 / 1024));
1576 else if (n < 1024 * 1024 * 1024)
1577 snprintf(s, size, "%u.%u MB", (unsigned int) n / (1024 * 1024), (unsigned int)(n % (1024 * 1024) * 10 / (1024 * 1024)));
1578 else if (n < (unsigned long long)1024 * 1024 * 1024 * 1024)
1579 snprintf(s, size, "%u.%u GB", (unsigned int) (n / (1024 * 1024 * 1024)), (unsigned int) (n % (1024 * 1024 * 1024) * 10 / (1024 * 1024 * 1024)));
1580 else
1581 snprintf(s, size, "%u.%u TB", (unsigned int) (n / ((unsigned long long)1024 * 1024 * 1024 * 1024)), (unsigned int)(n % ((unsigned long long)1024 * 1024 * 1024 * 1024) * 10 / ((unsigned long long)1024 * 1024 * 1024 * 1024)));
1583 return s;
1586 ////