001/*
002 * JavaCL - Java API and utilities for OpenCL
003 * http://javacl.googlecode.com/
004 *
005 * Copyright (c) 2009-2013, Olivier Chafik (http://ochafik.com/)
006 * All rights reserved.
007 *
008 * Redistribution and use in source and binary forms, with or without
009 * modification, are permitted provided that the following conditions are met:
010 * 
011 *     * Redistributions of source code must retain the above copyright
012 *       notice, this list of conditions and the following disclaimer.
013 *     * Redistributions in binary form must reproduce the above copyright
014 *       notice, this list of conditions and the following disclaimer in the
015 *       documentation and/or other materials provided with the distribution.
016 *     * Neither the name of Olivier Chafik nor the
017 *       names of its contributors may be used to endorse or promote products
018 *       derived from this software without specific prior written permission.
019 * 
020 * THIS SOFTWARE IS PROVIDED BY OLIVIER CHAFIK AND CONTRIBUTORS ``AS IS'' AND ANY
021 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
023 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030 */
031        
032
033
034
035
036        
037
038        
039        
040
041
042
043        
044
045        
046        
047        
048
049        
050package com.nativelibs4java.opencl;
051import static com.nativelibs4java.opencl.library.OpenCLLibrary.*;
052import static com.nativelibs4java.opencl.library.IOpenCLLibrary.*;
053
054import com.nativelibs4java.opencl.library.cl_image_format;
055import com.nativelibs4java.util.EnumValue;
056import com.nativelibs4java.util.EnumValues;
057import org.bridj.*;
058import static org.bridj.Pointer.*;
059
060/**
061 * OpenCL Image Format
062 * see {@link CLContext#getSupportedImageFormats(com.nativelibs4java.opencl.CLMem.Flags, com.nativelibs4java.opencl.CLMem.ObjectType) } 
063 * @author Olivier Chafik
064 */
065public class CLImageFormat {
066
067        private final ChannelOrder channelOrder;
068        private final ChannelDataType channelDataType;
069
070        CLImageFormat(cl_image_format fmt) {
071                this(ChannelOrder.getEnum(fmt.image_channel_order()), ChannelDataType.getEnum(fmt.image_channel_data_type()));
072        }
073        cl_image_format to_cl_image_format() {
074                return new cl_image_format().image_channel_order((int)channelOrder.value()).image_channel_data_type((int)channelDataType.value());
075        }
076        public CLImageFormat(ChannelOrder channelOrder, ChannelDataType channelDataType) {
077                super();
078                this.channelDataType = channelDataType;
079                this.channelOrder = channelOrder;
080        }
081
082        @Override
083        public boolean equals(Object obj) {
084                if (obj == null || !(obj instanceof CLImageFormat))
085                        return false;
086                CLImageFormat f = (CLImageFormat)obj;
087                if (channelOrder == null) {
088                        if (f.channelOrder != null)
089                                return false;
090                } else if (!channelOrder.equals(f.channelOrder))
091                        return false;
092
093
094                if (channelDataType == null) {
095                        return f.channelDataType == null;
096                } else return channelDataType.equals(f.channelDataType);
097        }
098
099        @Override
100        public int hashCode() {
101                int h = super.hashCode();
102                if (channelOrder != null)
103                        h ^= channelOrder.hashCode();
104                if (channelDataType != null)
105                        h ^= channelDataType.hashCode();
106                return h;
107        }
108
109        public boolean isIntBased() {
110                if (channelDataType == null || channelOrder == null)
111                        return false;
112                switch (getChannelOrder()) {
113                        case ARGB:
114                        case BGRA:
115                        case RGBA:
116                                switch (getChannelDataType()) {
117                                        case SNormInt8:
118                                        case SignedInt8:
119                                        case UNormInt8:
120                                        case UnsignedInt8:
121                                                return true;
122                                }
123                }
124                return false;
125        }
126        public final ChannelOrder getChannelOrder() {
127                return channelOrder;
128        }
129        public final ChannelDataType getChannelDataType() {
130                return channelDataType;
131        }
132
133        @Override
134        public String toString() {
135                return "(" + channelOrder + ", " + channelDataType + ")";
136        }
137
138
139
140        public enum ChannelOrder implements com.nativelibs4java.util.ValuedEnum {
141                
142                /**
143                 * components of channel data: (r, 0.0, 0.0, 1.0)
144                 */
145                R(CL_R),
146                /**
147                 * components of channel data: (r, 0.0, 0.0, 1.0)
148                 * @since OpenCL 1.1
149                 */
150                Rx(CL_Rx), 
151                /**
152                 * components of channel data: (0.0, 0.0, 0.0, a)
153                 */
154                A(CL_A),
155                /**
156                 * components of channel data: (I, I, I, I) <br>
157                 * This format can only be used if channel data type = CL_UNORM_INT8, CL_UNORM_INT16, CL_SNORM_INT8, CL_SNORM_INT16, CL_HALF_FLOAT or CL_FLOAT.
158                 */
159                INTENSITY(CL_INTENSITY),
160                /**
161                 * components of channel data: (L, L, L, 1.0) <br>
162                 * This format can only be used if channel data type = CL_UNORM_INT8, CL_UNORM_INT16, CL_SNORM_INT8, CL_SNORM_INT16, CL_HALF_FLOAT or CL_FLOAT.
163                 */
164                LUMINANCE(CL_LUMINANCE),
165                /**
166                 * components of channel data: (r, g, 0.0, 1.0)
167                 */
168                RG(CL_RG),
169                /**
170                 * components of channel data: (r, g, 0.0, 1.0)
171                 * @since OpenCL 1.1
172                 */
173                RGx(CL_RGx), 
174                /**
175                 * components of channel data: (r, 0.0, 0.0, a)
176                 */
177                RA(CL_RA),
178                /**
179                 * components of channel data: (r, g, b, 1.0) <br>
180                 * This format can only be used if channel data type = CL_UNORM_SHORT_565, CL_UNORM_SHORT_555 or CL_UNORM_INT101010.
181                 */
182                RGB(CL_RGB),
183                /**
184                 * components of channel data: (r, g, b, 1.0) <br>
185                 * This format can only be used if channel data type = CL_UNORM_SHORT_565, CL_UNORM_SHORT_555 or CL_UNORM_INT101010.
186                 * @since OpenCL 1.1
187                 */
188                RGBx(CL_RGBx),
189                /**
190                 * components of channel data: (r, g, b, a)
191                 */
192                RGBA(CL_RGBA),
193                /**
194                 * components of channel data: (r, g, b, a)
195                 */
196                ARGB(CL_ARGB),
197                /**
198                 * components of channel data: (r, g, b, a) <br>
199                 * This format can only be used if channel data type = CL_UNORM_INT8, CL_SNORM_INT8, CL_SIGNED_INT8 or CL_UNSIGNED_INT8.
200                 */
201                BGRA(CL_BGRA);
202
203
204                ChannelOrder(long value) { this.value = value; }
205                long value;
206                @Override
207                public long value() { return value; }
208                public static ChannelOrder getEnum(long v) { return EnumValues.getEnum(v, ChannelOrder.class); }
209
210        }
211
212        /**
213         * For example, to specify a normalized unsigned 8-bit / channel RGBA image, image_channel_order = CL_RGBA, and image_channel_data_type = CL_UNORM_INT8. The memory layout of this image format is described below:
214         */
215        public enum ChannelDataType implements com.nativelibs4java.util.ValuedEnum {
216                /**
217                 * Each channel component is a normalized signed 8-bit integer value
218                 */
219                SNormInt8(CL_SNORM_INT8, 8),
220                /**
221                 * Each channel component is a normalized signed 16-bit integer value
222                 */
223                SNormInt16(CL_SNORM_INT16, 16),
224                /**
225                 * Each channel component is a normalized unsigned 8-bit integer value
226                 */
227                UNormInt8(CL_UNORM_INT8, 8),
228                /**
229                 * Each channel component is a normalized unsigned 16- bit integer value
230                 */
231                UNormInt16(CL_UNORM_INT16, 16),
232                /**
233                 * Represents a normalized 5-6-5 3-channel RGB image. <br>
234                 * The channel order must be CL_RGB or CL_RGBx.<br>
235                 * CL_UNORM_SHORT_565 is a special cases of packed image format where the channels of each element are packed into a single unsigned short or unsigned int. <br>
236                 * For this special packed image format, the channels are normally packed with the first channel in the most significant bits of the bitfield, and successive channels occupying progressively less significant locations.<br>
237                 * For CL_UNORM_SHORT_565, R is in bits 15:11, G is in bits 10:5 and B is in bits 4:0.
238                 */
239                UNormShort565(CL_UNORM_SHORT_565, 16/* ?? */),
240                /**
241                 * Represents a normalized x-5-5-5 4-channel xRGB image. <br>
242                 * The channel order must be CL_RGB or CL_RGBx.<br>
243                 * CL_UNORM_SHORT_555 is a special cases of packed image format where the channels of each element are packed into a single unsigned short or unsigned int. <br>
244                 * For this special packed image format, the channels are normally packed with the first channel in the most significant bits of the bitfield, and successive channels occupying progressively less significant locations.<br>
245                 * For CL_UNORM_SHORT_555, bit 15 is undefined, R is in bits 14:10, G in bits 9:5 and B in bits 4:0.
246                 */
247                UNormShort555(CL_UNORM_SHORT_555, 15/* ?? */),
248                /**
249                 * Represents a normalized x-10-10-10 4-channel xRGB image. <br>
250                 * The channel order must be CL_RGB or CL_RGBx.<br>
251                 * CL_UNORM_INT_101010 is a special cases of packed image format where the channels of each element are packed into a single unsigned short or unsigned int. <br>
252                 * For this special packed image format, the channels are normally packed with the first channel in the most significant bits of the bitfield, and successive channels occupying progressively less significant locations.<br>
253                 * For CL_UNORM_INT_101010, bits 31:30 are undefined, R is in bits 29:20, G in bits 19:10 and B in bits 9:0.
254                 */
255                UNormInt101010(CL_UNORM_INT_101010, 30/* TODO ?? */),
256                /**
257                 * Each channel component is an unnormalized signed 8- bit integer value
258                 */
259                SignedInt8(CL_SIGNED_INT8, 8),
260                /**
261                 * Each channel component is an unnormalized signed 16- bit integer value
262                 */
263                SignedInt16(CL_SIGNED_INT16, 16),
264                /**
265                 * Each channel component is an unnormalized signed 32- bit integer value
266                 */
267                SignedInt32(CL_SIGNED_INT32, 32),
268                /**
269                 * Each channel component is an unnormalized unsigned 8-bit integer value
270                 */
271                UnsignedInt8(CL_UNSIGNED_INT8, 8),
272                /**
273                 * Each channel component is an unnormalized unsigned 16-bit integer value
274                 */
275                UnsignedInt16(CL_UNSIGNED_INT16, 16),
276                /**
277                 * Each channel component is an unnormalized unsigned 32-bit integer value
278                 */
279                UnsignedInt32(CL_UNSIGNED_INT32, 32),
280                /**
281                 * Each channel component is a 16-bit half-float value
282                 */
283                HalfFloat(CL_HALF_FLOAT, 16),
284                /**
285                 * Each channel component is a single precision floating- point value
286                 */
287                Float(CL_FLOAT, 32);
288
289                ChannelDataType(long value, int bits) {
290                        this.SIZE = bits;
291                        this.value = value; 
292                }
293                /**
294                 * Size of this ChannelDataType, in bits
295                 */
296                public final int SIZE;
297                long value;
298                @Override
299                public long value() { return value; }
300                public static ChannelDataType getEnum(long v) { return EnumValues.getEnum(v, ChannelDataType.class); }
301        }
302
303    static CLImageFormat INT_ARGB_FORMAT = new CLImageFormat(ChannelOrder.BGRA, ChannelDataType.UNormInt8);
304    //static CLImageFormat INT_ARGB_FORMAT = new CLImageFormat(ChannelOrder.RGBA, ChannelDataType.UNormInt8);
305}