25
25
** Note: So far saves just one frame. For multi-image formats it would be
26
26
** better to write a device (image:// port or something like that)
27
27
**
28
- ************************************************************************
29
- ** Useful links:
30
- ** https://chromium.googlesource.com/webm/webp-wic-codec
31
- ***********************************************************************/
32
-
28
+ ************************************************************************/
33
29
#include " sys-codecs.h"
34
- #include " sys-utils.h"
30
+ #define kSDUTTypeHEIC ((__bridge CFStringRef )@" public.heic" )
31
+ #define kSDUTTypeHEIF ((__bridge CFStringRef )@" public.heif" )
35
32
36
33
34
+ #ifdef unused
37
35
void listImageCodecs (void ){
38
36
// puts("Suppported codecs:");
39
37
CFArrayRef mySourceTypes = CGImageSourceCopyTypeIdentifiers ();
40
38
CFShow (mySourceTypes);
41
39
CFArrayRef myDestinationTypes = CGImageDestinationCopyTypeIdentifiers ();
42
40
CFShow (myDestinationTypes);
43
41
}
42
+ #endif
44
43
45
- CFURLRef urlFromCString (const char * cString){
46
- NSString *myNSString = [NSString stringWithUTF8String: cString];
47
- NSString *path = [myNSString stringByExpandingTildeInPath ];
48
- return CFURLCreateWithFileSystemPath (NULL , (CFStringRef )path, 0 , false );
49
- }
50
-
51
- CODECS_API int DecodeImageFromFile (const char *uri, unsigned int frame, REBCDI *codi)
44
+ int DecodeImageFromFile (const char *uri, unsigned int frame, REBCDI *codi)
52
45
{
53
46
int error = 0 ;
54
47
CFURLRef url = NULL ;
@@ -62,6 +55,7 @@ CODECS_API int DecodeImageFromFile(const char *uri, unsigned int frame, REBCDI *
62
55
NSUInteger w, h;
63
56
NSUInteger bytesPerPixel = 4 ;
64
57
NSUInteger bitsPerComponent = 8 ;
58
+
65
59
do {
66
60
if (uri) {
67
61
// decoding from file
@@ -87,7 +81,6 @@ CODECS_API int DecodeImageFromFile(const char *uri, unsigned int frame, REBCDI *
87
81
CGColorSpaceRelease (space);
88
82
CGContextRelease (ctx);
89
83
90
- // listImageCodecs();
91
84
codi->w = (UInt32 )w;
92
85
codi->h = (UInt32 )h;
93
86
codi->len = w * h * 4 ;
@@ -99,11 +92,17 @@ CODECS_API int DecodeImageFromFile(const char *uri, unsigned int frame, REBCDI *
99
92
return error;
100
93
}
101
94
102
- CODECS_API int EncodeImageToFile (const char *uri, REBCDI *codi)
95
+ int EncodeImageToFile (const char *uri, REBCDI *codi)
103
96
{
104
- int result = 0 ;
97
+ int error = 0 ;
105
98
CFStringRef type;
106
99
CFMutableDictionaryRef prop;
100
+ CGDataProviderRef data;
101
+ CGColorSpaceRef colorSpace;
102
+ CGImageRef img = NULL ;
103
+ CGImageDestinationRef imgDst = NULL ;
104
+ CFURLRef url;
105
+ CFDataRef dataDst;
107
106
108
107
switch (codi->type ) {
109
108
case CODI_IMG_PNG: type = kUTTypePNG ; break ; // Portable Network Graphics
@@ -112,43 +111,45 @@ CODECS_API int EncodeImageToFile(const char *uri, REBCDI *codi)
112
111
case CODI_IMG_GIF: type = kUTTypeGIF ; break ; // Graphics Interchange Format
113
112
case CODI_IMG_BMP: type = kUTTypeBMP ; break ; // Device independent bitmap
114
113
case CODI_IMG_TIFF: type = kUTTypeTIFF ; break ; // Tagged Image File Format
114
+ case CODI_IMG_HEIF: type = kSDUTTypeHEIC ; break ;
115
115
default :
116
116
codi->error = 1 ;
117
117
return codi->error ;
118
118
}
119
-
120
- CGDataProviderRef data = CGDataProviderCreateWithData (NULL , codi->bits , codi->w * codi->h * 4 , NULL );
121
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB ();
122
- CGImageRef img = CGImageCreate (codi->w , codi->h , 8 , 32 , codi->w * 4 , colorSpace, (kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big ), data, NULL , TRUE , 0 );
123
- CGDataProviderRelease (data);
124
- CGColorSpaceRelease (colorSpace);
125
-
126
- CFURLRef url;
127
- CGImageDestinationRef imgDst;
128
- CFDataRef dataDst;
129
- if (uri == NULL ) {
130
- // writing into preallocated buffer (fixed size!)
131
- TRACE_PTR (" dataTarget:" , &codi->data );
132
- dataDst = CFDataCreateWithBytesNoCopy (NULL , codi->data , codi->len , NULL );
133
- imgDst = CGImageDestinationCreateWithData ((CFMutableDataRef )dataDst, type, 1 , 0 );
134
- } else {
135
- // writing directly into file
136
- url = urlFromCString (uri);
137
- imgDst = CGImageDestinationCreateWithURL (url, type, 1 , 0 );
138
- }
139
- prop = CFDictionaryCreateMutable (NULL ,0 ,NULL ,NULL );
140
- CFDictionaryAddValue (prop, kCGImageDestinationLossyCompressionQuality , " 0.2" );
141
- CGFloat quality = 0.6 ;
142
- CGImageDestinationAddImage (imgDst, img, (__bridge CFDictionaryRef )@{(__bridge NSString *)kCGImageDestinationLossyCompressionQuality : @(quality)});
143
- CGImageDestinationFinalize (imgDst);
144
-
119
+ do {
120
+ data = CGDataProviderCreateWithData (NULL , codi->bits , codi->w * codi->h * 4 , NULL );
121
+ ASSERT_NOT_NULL (data, 1 , " prepare input data" );
122
+ colorSpace = CGColorSpaceCreateDeviceRGB ();
123
+ img = CGImageCreate (codi->w , codi->h , 8 , 32 , codi->w * 4 , colorSpace, (kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big ), data, NULL , TRUE , 0 );
124
+ CGDataProviderRelease (data);
125
+ CGColorSpaceRelease (colorSpace);
126
+ ASSERT_NOT_NULL (img, 2 , " create an image" );
127
+
128
+
129
+ if (uri == NULL ) {
130
+ // writing into preallocated buffer (fixed size!)
131
+ dataDst = CFDataCreateWithBytesNoCopy (NULL , codi->data , codi->len , NULL );
132
+ ASSERT_NOT_NULL (dataDst, 3 , " prepare output data" );
133
+ imgDst = CGImageDestinationCreateWithData ((CFMutableDataRef )dataDst, type, 1 , 0 );
134
+ } else {
135
+ // writing directly into file
136
+ url = urlFromCString (uri);
137
+ imgDst = CGImageDestinationCreateWithURL (url, type, 1 , 0 );
138
+ }
139
+ ASSERT_NOT_NULL (imgDst, 4 , " create a destination image" );
140
+ // TODO: handle user defined options
141
+ prop = CFDictionaryCreateMutable (NULL ,0 ,NULL ,NULL );
142
+ CFDictionaryAddValue (prop, kCGImageDestinationLossyCompressionQuality , " 0.2" );
143
+ CGFloat quality = 0.6 ;
144
+ CGImageDestinationAddImage (imgDst, img, (__bridge CFDictionaryRef )@{(__bridge NSString *)kCGImageDestinationLossyCompressionQuality : @(quality)});
145
+ CGImageDestinationFinalize (imgDst);
146
+ } while (FALSE );
145
147
if (uri == NULL ) {
146
- TRACE_PTR (" dataDst:" , &dataDst);
147
148
codi->len = CFDataGetLength (dataDst);
148
149
// CFRelease(dataDst);
149
150
}
150
- CFRelease (img);
151
- CFRelease (imgDst);
152
- codi->error = result ;
153
- return result ;
151
+ SAFE_CF_RELEASE (img);
152
+ SAFE_CF_RELEASE (imgDst);
153
+ codi->error = error ;
154
+ return error ;
154
155
}
0 commit comments