1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008-2010 Ricardo Quesada
  4  Copyright (c) 2011      Zynga Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * Image Format:JPG
 29  * @constant
 30  * @type Number
 31  */
 32 cc.FMT_JPG = 0;
 33 
 34 /**
 35  * Image Format:PNG
 36  * @constant
 37  * @type Number
 38  */
 39 cc.FMT_PNG = 1;
 40 
 41 /**
 42  * Image Format:TIFF
 43  * @constant
 44  * @type Number
 45  */
 46 cc.FMT_TIFF = 2;
 47 
 48 /**
 49  * Image Format:RAWDATA
 50  * @constant
 51  * @type Number
 52  */
 53 cc.FMT_RAWDATA = 3;
 54 
 55 /**
 56  * Image Format:WEBP
 57  * @constant
 58  * @type Number
 59  */
 60 cc.FMT_WEBP = 4;
 61 
 62 /**
 63  * Image Format:UNKNOWN
 64  * @constant
 65  * @type Number
 66  */
 67 cc.FMT_UNKNOWN = 5;
 68 
 69 /**
 70  * Horizontal center and vertical center.
 71  * @constant
 72  * @type Number
 73  */
 74 cc.ALIGN_CENTER = 0x33;
 75 
 76 /**
 77  * Horizontal center and vertical top.
 78  * @constant
 79  * @type Number
 80  */
 81 cc.ALIGN_TOP = 0x13;
 82 
 83 /**
 84  * Horizontal right and vertical top.
 85  * @constant
 86  * @type Number
 87  */
 88 cc.ALIGN_TOP_RIGHT = 0x12;
 89 
 90 /**
 91  * Horizontal right and vertical center.
 92  * @constant
 93  * @type Number
 94  */
 95 cc.ALIGN_RIGHT = 0x32;
 96 
 97 /**
 98  * Horizontal right and vertical bottom.
 99  * @constant
100  * @type Number
101  */
102 cc.ALIGN_BOTTOM_RIGHT = 0x22;
103 
104 /**
105  * Horizontal center and vertical bottom.
106  * @constant
107  * @type Number
108  */
109 cc.ALIGN_BOTTOM = 0x23;
110 
111 /**
112  * Horizontal left and vertical bottom.
113  * @constant
114  * @type Number
115  */
116 cc.ALIGN_BOTTOM_LEFT = 0x21;
117 
118 /**
119  * Horizontal left and vertical center.
120  * @constant
121  * @type Number
122  */
123 cc.ALIGN_LEFT = 0x31;
124 
125 /**
126  * Horizontal left and vertical top.
127  * @constant
128  * @type Number
129  */
130 cc.ALIGN_TOP_LEFT = 0x11;
131 
132 /**
133  * premultiply alpha, or the effect will wrong when want to use other pixel format in CCTexture2D,
134  * such as RGB888, RGB5A1
135  * @param {Number} vr
136  * @param {Number} vg
137  * @param {Number} vb
138  * @param {Number} va
139  * @return {Number}
140  * @constructor
141  */
142 cc.RGB_PREMULTIPLY_APLHA = function (vr, vg, vb, va) {
143     return ((vr * (va + 1)) >> 8) | ((vg * (va + 1) >> 8) << 8) | ((vb * (va + 1) >> 8) << 16) | ((va) << 24)
144 }
145 
146 /**
147  * image source
148  * @Class
149  * @Construct
150  * @param {Array||String} data
151  * @param {Number} size
152  * @param {Number} offset
153  */
154 cc.tImageSource = function (data, size, offset) {
155     this.data = data;
156     this.size = size || 0;
157     this.offset = offset || 0;
158 };
159 
160 cc.pngReadCallback = function (png_ptr, data, length) {
161     var isource = new cc.tImageSource();
162     isource = cc.png_get_io_ptr(png_ptr);
163 
164     if (isource.offset + length <= isource.size) {
165         cc.memcpy(data, isource.data + isource.offset, length);
166         isource.offset += length;
167     }
168     else {
169         cc.png_error(png_ptr, "pngReaderCallback failed");
170     }
171 };
172 
173 cc.getImageFormatByData = function (imgData) {
174     // if it is a png file buffer.
175     if (imgData.length > 8) {
176         if (imgData[0] == 0x89
177             && imgData[1] == 0x50
178             && imgData[2] == 0x4E
179             && imgData[3] == 0x47
180             && imgData[4] == 0x0D
181             && imgData[5] == 0x0A
182             && imgData[6] == 0x1A
183             && imgData[7] == 0x0A) {
184             return cc.FMT_PNG;
185         }
186     }
187 
188     // if it is a tiff file buffer.
189     if (imgData.length > 2) {
190         if ((imgData[0] == 0x49 && imgData[1] == 0x49)
191             || (imgData[0] == 0x4d && imgData[1] == 0x4d)
192             || (imgData[0] == 0xff && imgData[1] == 0xd8)) {
193             return cc.FMT_TIFF;
194         }
195     }
196 
197     return cc.FMT_UNKNOWN;
198 };
199 
200 /**
201  * Image
202  * @class
203  * @extends cc.Class
204  */
205 cc.Image = cc.Class.extend(/** @lends cc.Image# */{
206     _width: 0,
207     _height: 0,
208     _bitsPerComponent: 0,
209     _data: 0,
210     _hasAlpha: false,
211     _preMulti: false,
212 
213     /**
214      * Load the image from the specified path.
215      * @param {String} strPath the absolute file path
216      * @param {Number} imageType the type of image, now only support tow types.
217      * @return {Boolean} true if load correctly
218      */
219     initWithImageFile: function (strPath, imageType) {
220         var data = cc.FileUtils.getInstance().getFileData(strPath, "rb");
221         var size = data.length;
222         if (data != null && data.length > 0)
223             return this.initWithImageData(data, data.length, imageType);
224         return false;
225     },
226 
227     /**
228      * The same meaning as initWithImageFile, but it is thread safe. It is casued by loadImage() in cc.TextureCache.
229      * @param {String} fullpath full path of the file
230      * @param {Number} imageType the type of image, now only support tow types.
231      * @return {Boolean} true if load correctly
232      */
233     initWithImageFileThreadSafe: function (fullpath, imageType) {
234         return this.initWithImageFile(fullpath, imageType);
235     },
236 
237     /**
238      * Load image from stream buffer.
239      * @warning FMT_RAWDATA only support RGBA8888
240      * @param {Array} data stream buffer that hold the image data
241      * @param {Number} dataLen the length of data(managed in byte)
242      * @param {Number} eFmt
243      * @param {Number} width
244      * @param {Number} height
245      * @param {Number} bitsPerComponent
246      * @return {Boolean} true if load correctly
247      */
248     initWithImageData: function (data, dataLen, eFmt, width, height, bitsPerComponent) {
249         bitsPerComponent = bitsPerComponent || 8;
250         width = width || 0;
251         height = height || 0;
252         eFmt = eFmt || cc.FMT_UNKNOWN;
253 
254         if (!data || dataLen <= 0)
255             return false;
256 
257         if (cc.FMT_PNG == eFmt)
258             return this._initWithPngData(data, dataLen);
259         else if (cc.FMT_JPG == eFmt)
260             return this._initWithJpgData(data, dataLen);
261         else if (cc.FMT_TIFF == eFmt)
262             return this._initWithTiffData(data, dataLen);
263         else if (cc.FMT_RAWDATA == eFmt)
264             return this._initWithRawData(data, dataLen, width, height, bitsPerComponent);
265         else {
266             // if it is a png file buffer.
267             if (dataLen > 8) {
268                 if (data[0] == 0x89
269                     && data[1] == 0x50
270                     && data[2] == 0x4E
271                     && data[3] == 0x47
272                     && data[4] == 0x0D
273                     && data[5] == 0x0A
274                     && data[6] == 0x1A
275                     && data[7] == 0x0A) {
276                     return this._initWithPngData(data, dataLen);
277                 }
278             }
279 
280             // if it is a tiff file buffer.
281             if (dataLen > 2) {
282                 if ((data[0] == 0x49 && data[1] == 0x49)
283                     || (data[0] == 0x4d && data[1] == 0x4d)) {
284                     return this._initWithTiffData(data, dataLen);
285                 } else if (data[0] == 0xff && data[1] == 0xd8) {
286                     return this._initWithTiffData(data, dataLen);
287                 }
288             }
289         }
290         return false;
291     },
292 
293     getData: function () {
294         return this._data;
295     },
296 
297     getDataLen: function () {
298         return this._width * this._height;
299     },
300 
301     hasAlpha: function () {
302         return this._hasAlpha;
303     },
304 
305     isPremultipliedAlpha: function () {
306         return this._preMulti;
307     },
308 
309     getWidth: function () {
310         return this._width;
311     },
312 
313     getHeight: function () {
314         return this._height;
315     },
316 
317     getBitsPerComponent: function () {
318         return this._bitsPerComponent;
319     },
320 
321     /**
322      * Save the CCImage data to specified file with specified format.
323      * @param {String} filePath the file's absolute path, including file subfix
324      * @param {Boolean} isToRGB  if the image is saved as RGB format
325      * @return {Boolean}
326      */
327     saveToFile: function (filePath, isToRGB) {
328         //
329         cc.log("doesn't support saveToFile on Cocos2d-Html5");
330         return false;
331     },
332 
333     /*protected:*/
334     _initWithJpgData: function (data, dataLen) {
335         return false;
336     },
337 
338     _initWithPngData: function (data, datalen) {
339         return false;
340     },
341 
342     _initWithTiffData: function (data, dataLen) {
343         return false;
344     },
345 
346     // @warning FMT_RAWDATA only support RGBA8888
347     _initWithRawData: function (data, datalen, width, height, bitsPerComponent) {
348         return false;
349     },
350 
351     _saveImageToPNG: function (filePath, isToRGB) {
352         return false;
353     },
354 
355     _saveImageToJPG: function (filePath) {
356         return false;
357     },
358 
359     /**
360      * Create image with specified string.
361      * @param {String} text the text which the image show, nil cause init fail
362      * @param {Number} width the image width, if 0, the width match the text's width
363      * @param {Number} height the image height, if 0, the height match the text's height
364      * @param {Number} eAlignMask the test Alignment
365      * @param {String} fontName the name of the font which use to draw the text. If nil, use the default system font.
366      * @param {Number} size the font size, if 0, use the system default size.
367      * @return {Boolean}
368      */
369     initWithString: function (text, width, height, eAlignMask, fontName, size) {
370         return false;
371     }
372 });
373