1 | /* |
---|
2 | * libpipi Pathetic image processing interface library |
---|
3 | * Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org> |
---|
4 | * 2008 Jean-Yves Lamoureux <jylam@lnxscene.org> |
---|
5 | * All Rights Reserved |
---|
6 | * |
---|
7 | * $Id$ |
---|
8 | * |
---|
9 | * This library is free software. It comes without any warranty, to |
---|
10 | * the extent permitted by applicable law. You can redistribute it |
---|
11 | * and/or modify it under the terms of the Do What The Fuck You Want |
---|
12 | * To Public License, Version 2, as published by Sam Hocevar. See |
---|
13 | * http://sam.zoy.org/wtfpl/COPYING for more details. |
---|
14 | */ |
---|
15 | |
---|
16 | /* |
---|
17 | * coreimage.m: CoreImage (OSX) I/O functions |
---|
18 | */ |
---|
19 | |
---|
20 | #import "coreimage.h" |
---|
21 | |
---|
22 | #ifdef USE_COCOA |
---|
23 | #import <CIImage.h> |
---|
24 | |
---|
25 | |
---|
26 | static int pipi_free_coreimage(pipi_image_t *img); |
---|
27 | |
---|
28 | pipi_image_t *pipi_load_coreimage(const char *name) |
---|
29 | { |
---|
30 | NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; |
---|
31 | NSString *n = [NSString stringWithCString: name]; |
---|
32 | CIImage *source; |
---|
33 | NSURL *url = [NSURL fileURLWithPath:n]; |
---|
34 | |
---|
35 | source = [CIImage imageWithContentsOfURL:url]; |
---|
36 | |
---|
37 | if(source == NULL) return NULL; |
---|
38 | |
---|
39 | CGRect extent = [source extent]; |
---|
40 | size_t w = (size_t)extent.size.width; |
---|
41 | size_t h = (size_t)extent.size.height; |
---|
42 | |
---|
43 | |
---|
44 | NSBitmapImageRep * myImage; |
---|
45 | myImage = [[NSBitmapImageRep alloc] initWithCIImage:source]; |
---|
46 | |
---|
47 | pipi_image_t *img; |
---|
48 | img = pipi_new(w, h); |
---|
49 | |
---|
50 | img->p[PIPI_PIXELS_RGBA_C].w = w; |
---|
51 | img->p[PIPI_PIXELS_RGBA_C].h = h; |
---|
52 | img->p[PIPI_PIXELS_RGBA_C].pitch = ([myImage bytesPerRow]/8) * img->w; |
---|
53 | img->p[PIPI_PIXELS_RGBA_C].bpp = [myImage bitsPerPixel]; |
---|
54 | img->p[PIPI_PIXELS_RGBA_C].bytes = ([myImage bitsPerPixel]/8) * img->w * img->h; |
---|
55 | img->last_modified = PIPI_PIXELS_RGBA_C; |
---|
56 | |
---|
57 | |
---|
58 | /* CoreImage feeds us with BGRA while we need RGBA, so convert it. |
---|
59 | * We also need to get a pitch==(w*bpp) in order to pipi to opper properly. |
---|
60 | */ |
---|
61 | |
---|
62 | int pitch = (img->p[PIPI_PIXELS_RGBA_C].bpp/8); |
---|
63 | unsigned char *tmp = (unsigned char*)malloc(h*w*pitch); |
---|
64 | unsigned char *orig = (unsigned char*)[myImage bitmapData]; |
---|
65 | int x, y, k=0, o=0, a=[myImage bytesPerRow] - (w*([myImage bitsPerPixel]/8)); |
---|
66 | |
---|
67 | for(y=0; y<h; y++) |
---|
68 | { |
---|
69 | for(x=0; x<w*pitch; x+=4) |
---|
70 | { |
---|
71 | if(!([myImage bitmapFormat] & NSAlphaFirstBitmapFormat)) |
---|
72 | { |
---|
73 | tmp[k+2] = orig[o]; |
---|
74 | tmp[k+1] = orig[o+1]; |
---|
75 | tmp[k+0] = orig[o+2]; |
---|
76 | tmp[k+3] = orig[o+3]; |
---|
77 | } else |
---|
78 | { |
---|
79 | tmp[k+0] = orig[o]; |
---|
80 | tmp[k+1] = orig[o+1]; |
---|
81 | tmp[k+2] = orig[o+2]; |
---|
82 | tmp[k+3] = orig[o+3]; |
---|
83 | } |
---|
84 | |
---|
85 | o+=4; |
---|
86 | k+=4; |
---|
87 | } |
---|
88 | o+=a; |
---|
89 | } |
---|
90 | img->p[PIPI_PIXELS_RGBA_C].pixels = tmp; |
---|
91 | img->p[PIPI_PIXELS_RGBA_C].pitch = w*([myImage bitsPerPixel]/8); |
---|
92 | |
---|
93 | |
---|
94 | |
---|
95 | |
---|
96 | img->codec_priv = (struct pipi_codec_coreimage *) malloc(sizeof(struct pipi_codec_coreimage *)); |
---|
97 | struct pipi_codec_coreimage *infos = (struct pipi_codec_coreimage *) img->codec_priv; |
---|
98 | infos->format = [myImage bitmapFormat]; |
---|
99 | |
---|
100 | pipi_pixels_t *p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C); |
---|
101 | |
---|
102 | img->codec_free = pipi_free_coreimage; |
---|
103 | |
---|
104 | [autoreleasepool release]; |
---|
105 | return img; |
---|
106 | } |
---|
107 | |
---|
108 | |
---|
109 | int pipi_save_coreimage(pipi_image_t *img, const char *name) |
---|
110 | { |
---|
111 | NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; |
---|
112 | printf("%d\n", img->last_modified); |
---|
113 | pipi_pixels_t *p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C); |
---|
114 | |
---|
115 | NSString *n = [NSString stringWithCString: name]; |
---|
116 | NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] |
---|
117 | initWithBitmapDataPlanes:NULL |
---|
118 | pixelsWide:p->w |
---|
119 | pixelsHigh:p->h |
---|
120 | bitsPerSample:8 |
---|
121 | samplesPerPixel:4 |
---|
122 | hasAlpha:YES |
---|
123 | isPlanar:NO |
---|
124 | colorSpaceName:NSCalibratedRGBColorSpace |
---|
125 | bitmapFormat: 0//(NSBitmapFormat)img->codec_priv |
---|
126 | bytesPerRow:p->w*4 |
---|
127 | bitsPerPixel:32 |
---|
128 | ]; |
---|
129 | if(bitmap == nil) return -1; |
---|
130 | memcpy([bitmap bitmapData], p->pixels, p->w*p->h*4); |
---|
131 | |
---|
132 | NSBitmapImageFileType type = NSPNGFileType; |
---|
133 | |
---|
134 | |
---|
135 | if(strlen(name) > 4) |
---|
136 | { |
---|
137 | char *ext = (char*)&name[strlen(name) - 4]; |
---|
138 | if( !strncasecmp(ext, ".png", 3)) type = NSPNGFileType; |
---|
139 | else if(!strncasecmp(ext, "jpeg", 4)) type = NSJPEGFileType; |
---|
140 | else if(!strncasecmp(ext, ".jpg", 3)) type = NSJPEGFileType; |
---|
141 | else if(!strncasecmp(ext, ".bmp", 3)) type = NSBMPFileType; |
---|
142 | else if(!strncasecmp(ext, ".tif", 3)) type = NSTIFFFileType; |
---|
143 | else if(!strncasecmp(ext, ".tiff", 3)) type = NSTIFFFileType; |
---|
144 | else if(!strncasecmp(ext, ".gif", 3)) type = NSGIFFileType; |
---|
145 | else if(!strncasecmp(ext, ".bmp", 3)) type = NSBMPFileType; |
---|
146 | else if(!strncasecmp(ext, ".jp2", 3)) type = NSJPEG2000FileType; |
---|
147 | else if(!strncasecmp(ext, ".j2k", 3)) type = NSJPEG2000FileType; |
---|
148 | } |
---|
149 | |
---|
150 | [[bitmap representationUsingType:type properties:nil] writeToFile:n atomically:YES]; |
---|
151 | [autoreleasepool release]; |
---|
152 | |
---|
153 | return 1; |
---|
154 | } |
---|
155 | |
---|
156 | /* |
---|
157 | * XXX: The following functions are local. |
---|
158 | */ |
---|
159 | |
---|
160 | static int pipi_free_coreimage(pipi_image_t *img) |
---|
161 | { |
---|
162 | if(img->codec_priv) |
---|
163 | free(img->codec_priv); |
---|
164 | return 0; |
---|
165 | } |
---|
166 | |
---|
167 | #endif |
---|