19 #include <Carbon/Carbon.h>
20 #include <ApplicationServices/ApplicationServices.h>
21 #include <QuickTime/ImageCompression.h>
22 #include <QuickTime/QuickTimeComponents.h>
25 #include <sys/param.h>
27 #define ERR_NO_ERROR 0
31 #define ERR_UNSUPPORTED 4
32 #define ERR_BAD_DEPTH 5
76 case 0x03020100:
return false;
77 case 0x00010203:
return true;
79 assert(0 &&
"system has unknown endianness");
95 static char base[MAXPATHLEN];
99 if (path == NULL || *path ==
'\0')
return NULL;
102 eptr = path + strlen(path) - 1;
103 while (*eptr ==
'/' && path <= eptr) eptr--;
105 if (eptr == path && *eptr ==
'/') {
112 while (sptr > path && *(sptr - 1) !=
'/') sptr--;
114 if (eptr - sptr + 1 >
sizeof(base)) {
118 strncpy(base, sptr, eptr - sptr + 1);
119 base[eptr - sptr + 1] =
'\0';
127 static char dirpath [MAXPATHLEN];
130 if (path == NULL || *path ==
'\0')
return NULL;
133 ptr = path + strlen(path) - 1;
134 while (*ptr ==
'/' && path <= ptr) ptr--;
137 while (*ptr !=
'/' && path <= ptr) ptr--;
140 if (ptr == path && *ptr ==
'/') {
141 strcpy(dirpath,
"/");
147 strcpy(dirpath,
".");
151 if ((
unsigned int)(ptr - path + 1) >
sizeof(dirpath)) {
155 strncpy(dirpath, path, ptr - path + 1);
156 dirpath[ptr - path + 1] =
'\0';
175 char fullpath [MAXPATHLEN];
181 realpath(filename, fullpath);
182 FSPathMakeRef((
const UInt8 *)
cc_dirname(fullpath), &path,
false);
185 cfstr = CFStringCreateWithCString(0,
cc_basename(fullpath),
186 CFStringGetSystemEncoding());
187 len = CFStringGetLength(cfstr);
188 ustr = malloc(len *
sizeof(UniChar));
189 CFStringGetCharacters(cfstr, CFRangeMake(0, len), ustr);
191 FSMakeFSRefUnicode (&path, len, ustr, CFStringGetSystemEncoding(), &file);
192 e = FSGetCatalogInfo(&file, kFSCatInfoNone, NULL, NULL, &fss, NULL);
193 if (e != noErr)
return 0;
195 if (GetGraphicsImporterForFile(&fss, c) == noErr)
return 1;
206 ComponentDescription cd;
207 cd.componentType = GraphicsExporterComponentType;
208 cd.componentSubType = 0;
209 cd.componentManufacturer = 0;
210 cd.componentFlags = 0;
211 cd.componentFlagsMask = graphicsExporterIsBaseExporter;
213 if (!fext || !ge)
return;
215 while ((c = FindNextComponent (c, &cd)) != 0) {
216 char * cstr = malloc(5);
217 OSType * ext = malloc(
sizeof(OSType));
218 GraphicsExportGetDefaultFileNameExtension((GraphicsExportComponent)c, ext);
222 uint8_t * block = (uint8_t*)ext;
230 memcpy(cstr, ext, 4);
231 if (cstr[3] ==
' ') cstr[3] =
'\0';
233 if (strcasecmp(fext, cstr) == 0) {
234 OpenAComponent(c, ge);
252 if (cstr[3] ==
' ') cstr[3] =
'\0';
254 CFStringAppendCString(str, cstr, CFStringGetSystemEncoding());
272 char fullpath [MAXPATHLEN];
274 realpath(filename, fullpath);
275 e = FSPathMakeRef((
const UInt8 *)
cc_dirname(fullpath), &path,
false);
276 if (e != noErr)
return 0;
279 cfstr = CFStringCreateWithCString(0,
cc_basename(fullpath),
280 CFStringGetSystemEncoding());
281 len = CFStringGetLength(cfstr);
282 ustr = malloc(len *
sizeof(UniChar));
283 CFStringGetCharacters(cfstr, CFRangeMake(0, len), ustr);
286 e = FSMakeFSRefUnicode(&path, len, ustr, CFStringGetSystemEncoding(), &file);
287 if (e == noErr) FSDeleteObject(&file);
289 e = FSCreateFileUnicode (&path, len, ustr, 0, NULL, NULL, fss);
292 if (e == noErr)
return 1;
303 v_flip(
const unsigned char * px,
int width,
int height,
304 int numcomponents,
unsigned char * newpx)
312 for (i = 0; i < height; i++) {
313 memcpy (newpx + (i * width * numcomponents),
314 px + (((height - i) - 1) * numcomponents * width),
315 numcomponents * width);
328 for (i = 0; i < (height * width); i++)
329 *(px+i) = ((*(px+i) & 0x00FFFFFF ) << 8) | ((*(px+i) >> 24) & 0x000000FF);
331 for (i = 0; i < (height * width); i++)
332 *(px+i) = ((*(px+i) & 0x000000FF ) << 24) | ((*(px+i) >> 8) & 0x00FFFFFF);
345 for (i = 0; i < (height * width); i++)
346 *(px+i) = ((*(px+i) & 0xFFFFFF00 ) >> 8) | ((*(px+i) << 24) & 0xFF000000);
348 for (i = 0; i < (height * width); i++)
349 *(px+i) = ((*(px+i) & 0xFF000000 ) >> 24) | ((*(px+i) << 8) & 0xFFFFFF00);
362 strncpy(cstr,
"QuickTime loader: Error opening file", buflen);
365 strncpy(cstr,
"QuickTime loader: Internal graphics error", buflen);
368 strncpy(cstr,
"QuickTime saver: Error writing file", buflen);
371 strncpy(cstr,
"QuickTime saver: Unsupported file format", buflen);
374 strncpy(cstr,
"QuickTime saver: Only 24 and 32 bit images supported",
378 strncpy(cstr,
"QuickTime loader/saver: Out of memory", buflen);
389 GraphicsImportComponent c;
398 int * height,
int * numcomponents)
400 GraphicsImportComponent gi;
401 ImageDescriptionHandle desch = NULL;
402 ImageDescription * desc;
404 unsigned char * newpx = NULL;
414 e = GraphicsImportGetImageDescription(gi, &desch);
415 if(e != noErr || desch == NULL) {
421 bi.
width = desc->width;
428 if(bi.
data == NULL) {
438 QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &r, NULL,
440 GraphicsImportSetGWorld(gi, gw, NULL);
441 e = GraphicsImportDraw(gi);
444 if(bi.
data != NULL) {
455 GraphicsImportGetMatrix(gi, &mr);
456 ScaleMatrix(&mr, fixed1, Long2Fix(-1), 0, 0);
457 TranslateMatrix(&mr, 0, Long2Fix(r.bottom));
458 GraphicsImportSetMatrix(gi, &mr);
463 DisposeHandle((Handle)desch);
470 if(bi.
data != NULL) {
480 CFMutableStringRef ret = CFStringCreateMutable (NULL, 0);
482 bool firstext =
true;
485 OSType * ext = malloc(
sizeof(OSType));
488 ComponentDescription cd;
489 cd.componentType = GraphicsExporterComponentType;
490 cd.componentSubType = 0;
491 cd.componentManufacturer = 0;
492 cd.componentFlags = 0;
493 cd.componentFlagsMask = graphicsExporterIsBaseExporter;
495 while ((c = FindNextComponent (c, &cd)) != 0) {
497 if (firstext) firstext =
false;
498 else CFStringAppendCString(ret,
",", CFStringGetSystemEncoding());
499 GraphicsExportGetDefaultFileNameExtension((GraphicsExportComponent)c, ext);
503 uint8_t * block = (uint8_t*)ext;
515 CFIndex length = CFStringGetLength(ret) + 1;
518 cstr = malloc(length);
521 if (!CFStringGetCString(ret, cstr, length, CFStringGetSystemEncoding())) {
530 int width,
int height,
int numcomponents,
531 const char * filetypeext)
535 GraphicsExportComponent ge;
537 Rect r = {0, 0, height, width};
538 unsigned char * newpx = malloc(width * height * numcomponents);
540 v_flip(px, width, height, numcomponents, newpx);
547 if (numcomponents == 4) {
549 e = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &r, NULL,
550 NULL, 0, newpx, width * numcomponents);
551 }
else if (numcomponents == 3) {
552 e = QTNewGWorldFromPtr(&gw, k24RGBPixelFormat, &r, NULL,
553 NULL, 0, newpx, width * numcomponents);
575 GraphicsExportSetInputGWorld(ge, gw);
576 GraphicsExportSetOutputFile(ge, &fss);
577 e = GraphicsExportDoExport(ge, NULL);
static void open_exporter(const char *fext, GraphicsExportComponent *ge)
static char * cc_basename(const char *path)
unsigned char * simage_quicktime_load(const char *file, int *width, int *height, int *numcomponents)
static void rgba_to_argb(uint32_t *px, int width, int height)
static void argb_to_rgba(uint32_t *px, int width, int height)
static void v_flip(const unsigned char *px, int width, int height, int numcomponents, unsigned char *newpx)
static int create_file(const char *filename, FSSpec *fss)
char * simage_quicktime_get_savers(void)
int simage_quicktime_save(const char *filename, const unsigned char *px, int width, int height, int numcomponents, const char *filetypeext)
static int get_importer(const char *filename, GraphicsImportComponent *c)
static bool system_is_bigendian(void)
static char * cc_dirname(const char *path)
int simage_quicktime_error(char *cstr, int buflen)
static void cfstring_append_ostype(CFMutableStringRef str, OSType *t)
int simage_quicktime_identify(const char *file, const unsigned char *header, int headerlen)
static int quicktimeerror