bitmap.h.patch.h

Jeru, 02/08/2011 05:45 pm

Download (39 kB)

 
1
diff -r 4ea92975a277 code/nel/include/nel/misc/bitmap.h
2
--- a/code/nel/include/nel/misc/bitmap.h        Tue Feb 01 18:56:55 2011 +0100
3
+++ b/code/nel/include/nel/misc/bitmap.h        Tue Feb 08 16:37:37 2011 +0100
4
@@ -1,652 +1,643 @@
5
-// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
6
-// Copyright (C) 2010  Winch Gate Property Limited
7
-//
8
-// This program is free software: you can redistribute it and/or modify
9
-// it under the terms of the GNU Affero General Public License as
10
-// published by the Free Software Foundation, either version 3 of the
11
-// License, or (at your option) any later version.
12
-//
13
-// This program is distributed in the hope that it will be useful,
14
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
-// GNU Affero General Public License for more details.
17
-//
18
-// You should have received a copy of the GNU Affero General Public License
19
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
-
21
-
22
-#ifndef NL_BITMAP_H
23
-#define NL_BITMAP_H
24
-
25
-
26
-#include "types_nl.h"
27
-#include "rgba.h"
28
-#include "debug.h"
29
-#include <vector>
30
-#include "object_vector.h"
31
-
32
-
33
-namespace NLMISC
34
-{
35
-
36
-
37
-class IStream;
38
-
39
-//------------------ DDS STUFFS --------------------
40
-
41
-#ifndef NL_MAKEFOURCC
42
-        #ifdef NL_LITTLE_ENDIAN
43
-                #define NL_MAKEFOURCC(ch0, ch1, ch2, ch3) \
44
-                        ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
45
-                        ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
46
-        #else
47
-                #define NL_MAKEFOURCC(ch0, ch1, ch2, ch3) \
48
-                        ((uint32)(uint8)(ch3) | ((uint32)(uint8)(ch2) << 8) | \
49
-                        ((uint32)(uint8)(ch1) << 16) | ((uint32)(uint8)(ch0) << 24 ))
50
-        #endif
51
-#endif
52
-
53
-const uint32        DDS_HEADER = NL_MAKEFOURCC('D', 'D', 'S', ' ');
54
-const uint32        DXT_HEADER = NL_MAKEFOURCC('D', 'X', 'T', '\0');
55
-const uint32        PNG_HEADER = NL_MAKEFOURCC(0x89, 'P', 'N', 'G');
56
-const uint32        JPG_HEADER = NL_MAKEFOURCC(0xff, 0xd8, 0xff, 0xe0);
57
-
58
-
59
-// dwLinearSize is valid
60
-#define DDSD_LINEARSIZE         0x00080000l
61
-
62
-
63
-//---------------- END OF DDS STUFFS ------------------
64
-
65
-
66
-const uint8        MAX_MIPMAP = 16;
67
-
68
-
69
-
70
-
71
-/**
72
- * Class Bitmap
73
- *
74
- * \author Stephane Coutelas
75
- * \author Nevrax France
76
- * \date 2000
77
- */
78
-/* *** IMPORTANT ********************
79
- * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL
80
- * **********************************
81
- */
82
-class CBitmap
83
-{
84
-protected :
85
-        CObjectVector<uint8> _Data[MAX_MIPMAP];
86
-
87
-        // The number of mipmaps. base image IS a mipmap. 1 means a base image with no mipmaping.
88
-        uint8        _MipMapCount;
89
-        bool        _LoadGrayscaleAsAlpha;
90
-        uint32        _Width;
91
-        uint32        _Height;
92
-
93
-        // don't forget to update operator=() and swap() if adding a data member
94
-
95
-private :
96
-
97
-
98
-        /**
99
-         * blend 2 integers between 0 and 255 .
100
-         * \param n0 first integer
101
-         * \param n1 second integer
102
-         * \param coef coefficient for the first integer (must be in [0,256])
103
-         */
104
-        uint32 blend(uint32 &n0, uint32 &n1, uint32 coef0);
105
-
106
-
107
-        /**
108
-         * Read a DDS from an IStream.
109
-         * The bitmap is readen as a set of bytes and stocked compressed.
110
-         * Width and Height are multiple of 4.
111
-         * \param IStream The stream must be in reading mode.
112
-         * \return image depth
113
-         * \throw EDDSBadHeader : surface is header is not valid.
114
-         */
115
-        uint8 readDDS(NLMISC::IStream &f, uint mipMapSkip);
116
-
117
-
118
-        /**
119
-         * Read a TGA from an IStream.
120
-         * TGA pictures can be in 24 or 32 bits, RLE or uncompressed
121
-         * \param f IStream (must be a reading stream)
122
-         * \return image depth if succeed, 0 else
123
-         */
124
-        uint8 readTGA(        NLMISC::IStream &f);
125
-
126
-
127
-        /**
128
-         * Read a PNG from an IStream.
129
-         * PNG pictures can be in 24 or 32 bits
130
-         * \param f IStream (must be a reading stream)
131
-         * \return image depth if succeed, 0 else
132
-         */
133
-        uint8 readPNG( NLMISC::IStream &f );
134
-
135
-
136
-        /**
137
-         * Read a JPG from an IStream.
138
-         * JPG pictures can be in 24
139
-         * \param f IStream (must be a reading stream)
140
-         * \return image depth if succeed, 0 else
141
-         */
142
-        uint8 readJPG( NLMISC::IStream &f );
143
-
144
-
145
-        /**
146
-         * Change bitmap format
147
-         *
148
-         * about DXTC1 to DXTC5 :
149
-         * Does nothing if the format is not DXTC1
150
-         * about alpha encoding :
151
-         *                alpha0 == alpha1
152
-         *                code(x,y) == 7 for every (x,y)
153
-         *
154
-         * about luminance to alpha and alpha to luminance :
155
-         *      the buffer keeps unchanged
156
-         *
157
-         */
158
-        ///@{
159
-        bool convertToDXTC5();
160
-
161
-        bool convertToRGBA();
162
-        bool luminanceToRGBA();
163
-        bool alphaToRGBA();
164
-        bool alphaLuminanceToRGBA();
165
-
166
-        bool convertToLuminance();
167
-        bool rgbaToLuminance();
168
-        bool alphaToLuminance();
169
-        bool alphaLuminanceToLuminance();
170
-
171
-        bool convertToAlpha();
172
-        bool rgbaToAlpha();
173
-        bool luminanceToAlpha();
174
-        bool alphaLuminanceToAlpha();
175
-
176
-        bool convertToAlphaLuminance();
177
-        bool rgbaToAlphaLuminance();
178
-        bool luminanceToAlphaLuminance();
179
-        bool alphaToAlphaLuminance();
180
-
181
-        ///@}
182
-
183
-        /**
184
-         * Decompress bitmap compressed with S3TC DXT1 algorithm.
185
-         * \param alpha if alpha is true there's alpha.
186
-         */
187
-        bool decompressDXT1(bool alpha);
188
-
189
-        /**
190
-         * Decompress bitmap compressed with S3TC DXT3 algorithm.
191
-         * \throw EAllocationFailure : can't allocate memory.
192
-         */
193
-        bool decompressDXT3();
194
-
195
-
196
-        /**
197
-         * Decompress bitmap compressed with S3TC DXT3 algorithm.
198
-         * \throw EAllocationFailure : can't allocate memory.
199
-         */
200
-        bool decompressDXT5();
201
-
202
-
203
-        /**
204
-         * Extracting RGBA infos from a 16bits word. (used by S3TC decompression)
205
-         * \param color a 16bits integer
206
-         * \param r a CRGBA
207
-         */
208
-        static void uncompress(uint16 color, NLMISC::CRGBA &);
209
-
210
-
211
-        /**
212
-         * The resample function
213
-         * \param pSrc CRGBA array
214
-         * \param pDest CRGBA array for storing resampled texture
215
-         * \param nSrcWidth original width
216
-         * \param nSrcHeight original height
217
-         * \param nDestWidth width after resample
218
-         * \param nDestHeight height after resample
219
-         */
220
-        void resamplePicture32 (const NLMISC::CRGBA *pSrc, NLMISC::CRGBA *pDest,
221
-                                                         sint32 nSrcWidth, sint32 nSrcHeight,
222
-                                                         sint32 nDestWidth, sint32 nDestHeight);
223
-
224
-        /**
225
-         * The FAST resample function : works only when reducing the size by two
226
-         * and when the image is square
227
-         * \param pSrc CRGBA array
228
-         * \param pDest CRGBA array for storing resampled texture
229
-         * \param nSrcWidth original width
230
-         * \param nSrcHeight original height
231
-         * \param nDestWidth width after resample
232
-         * \param nDestHeight height after resample
233
-         */
234
-        void resamplePicture32Fast (const NLMISC::CRGBA *pSrc, NLMISC::CRGBA *pDest,
235
-                                                                sint32 nSrcWidth, sint32 nSrcHeight,
236
-                                                                sint32 nDestWidth, sint32 nDestHeight);
237
-
238
-
239
-        /**
240
-         * Quadratic interpolator
241
-         * \return the interpolation in (x,y) of the values (xy**)
242
-         */
243
-        float getColorInterp (float x, float y, float xy00, float xy01, float xy10, float xy11) const;
244
-
245
-
246
-        /// name  DXTC single texel read
247
-        //@{
248
-                static CRGBA getDXTCColorFromBlock(const uint8 *block, sint x, sint y);
249
-                CRGBA getDXTC1Texel(sint x, sint y, uint32 numMipMap) const;
250
-                CRGBA getDXTC3Texel(sint x, sint y, uint32 numMipMap) const;
251
-                CRGBA getDXTC5Texel(sint x, sint y, uint32 numMipMap) const;
252
-        //@}
253
-
254
-
255
-        CRGBA getRGBAPixel(sint x, sint y, uint32 numMipMap /*=0*/) const;
256
-
257
-
258
-        // Make a dummy from a bitfield
259
-        void        makeDummyFromBitField(const uint8        bitmap[1024]);
260
-
261
-        // Flip DXTC
262
-        void        flipHDXTCBlockColor(uint8 *bitColor, uint32 w);
263
-        void        flipVDXTCBlockColor(uint8 *bitColor, uint32 h);
264
-        void        flipHDXTCBlockAlpha3(uint8 *bitColor, uint32 w);
265
-        void        flipVDXTCBlockAlpha3(uint8 *bitColor, uint32 h);
266
-        void        flipHDXTCBlockAlpha5(uint8 *bitColor, uint32 w);
267
-        void        flipVDXTCBlockAlpha5(uint8 *bitColor, uint32 h);
268
-        void        flipDXTC(bool vertical);
269
-        void        flipDXTCMipMap(bool vertical, uint mm, uint type);
270
-
271
-public:
272
-
273
-        enum TType
274
-        {
275
-                RGBA=0,
276
-                Luminance,
277
-                Alpha,
278
-                AlphaLuminance,
279
-                DXTC1,
280
-                DXTC1Alpha,
281
-                DXTC3,
282
-                DXTC5,
283
-                DsDt,
284
-                ModeCount,
285
-                DonTKnow=0xffffffff
286
-        } PixelFormat;
287
-
288
-        static const uint32 bitPerPixels[ModeCount];
289
-        static const uint32 DXTC1HEADER;
290
-        static const uint32 DXTC3HEADER;
291
-        static const uint32 DXTC5HEADER;
292
-
293
-        // don't forget to update operator=() and swap() if adding a data member
294
-
295
-        CBitmap()
296
-        {
297
-                _MipMapCount = 1;
298
-                _Width = 0;
299
-                _Height = 0;
300
-                PixelFormat = RGBA;
301
-                _LoadGrayscaleAsAlpha = true;
302
-        }
303
-
304
-        virtual ~CBitmap() { }
305
-
306
-        // swap 2 bitmaps contents
307
-        void        swap(CBitmap &other);
308
-
309
-        /**
310
-         * Read a bitmap(TGA or DDS) from an IStream.
311
-         * Bitmap supported are DDS (DXTC1, DXTC1 with Alpha, DXTC3, DXTC5, and
312
-         * uncompressed TGA (24 and 32 bits).
313
-         * \param IStream The stream must be in reading mode.
314
-         * \param mipMapSkip if the file is a DDS with mipMap. N=mipMapSkip mipmaps are skipped.
315
-         * \return image depth (24 or 32), or 0 if load failed
316
-         * \throw ESeekFailed : seek has failed
317
-         */
318
-        uint8        load(NLMISC::IStream &f, uint mipMapSkip=0);
319
-
320
-
321
-        /**
322
-         * Determinate the bitmap size from a bitmap(TGA or DDS) from an IStream. load just header of the file.
323
-         * Bitmap supported are DDS (DXTC1, DXTC1 with Alpha, DXTC3, DXTC5, and
324
-         * uncompressed TGA (24 and 32 bits).
325
-         * NB: at the end, f is seeked to begin.
326
-         * \param IStream The stream must be in reading mode.
327
-         * \param width the width of the image. 0 if fails.
328
-         * \param height the height of the image. 0 if fails.
329
-         * \throw ESeekFailed : seek has failed
330
-         */
331
-        static void                loadSize(NLMISC::IStream &f, uint32 &width, uint32 &height);
332
-
333
-
334
-        /** same than other loadSize(), but with a pathName.
335
-         * \see loadSize()
336
-         */
337
-        static void                loadSize(const std::string &path, uint32 &retWidth, uint32 &retHeight);
338
-
339
-
340
-        /**
341
-         * Make a dummy "?" texture. Useful for file not found. Mode is rgba.
342
-         */
343
-        void        makeDummy();
344
-
345
-
346
-        /**
347
-         * Make a dummy "2" texture. Useful for file not power of 2. Mode is rgba.
348
-         */
349
-        void        makeNonPowerOf2Dummy();
350
-
351
-        /**
352
-         * Return the pixels buffer of the image, or of one of its mipmap.
353
-         * Return a reference of an array in pixel format get with getPixelFormat().
354
-         * \return CObjectVector<uint8>& RGBA pixels
355
-         */
356
-        ///@{
357
-        CObjectVector<uint8>& getPixels(uint32 numMipMap = 0)
358
-        {
359
-                //nlassert (numMipMap<=_MipMapCount);
360
-                return _Data[numMipMap];
361
-        }
362
-        const CObjectVector<uint8>& getPixels(uint32 numMipMap = 0) const
363
-        {
364
-                //nlassert (numMipMap<=_MipMapCount);
365
-                return _Data[numMipMap];
366
-        }
367
-        /** Gain ownership of this texture datas. As a result, the bitmap is reseted (put in the same state than when ctor is called, e.g a single mipmap with null size)
368
-          * The CObjectVector objects that contains the bitmap (one per mipmap) datas are 'swapped' with those in the array  provided by the caller.
369
-          * NB : The user must provide at least min(getMipMapCount(), maxMipMapCount) entries in the array
370
-          * \param mipmapArray Array of mipmap that receive the bitmap datas
371
-          * \param maxMipMapCount Max number of mipmap to be copied in the destination array.
372
-          */
373
-        void unattachPixels(CObjectVector<uint8> *mipmapDestArray, uint maxMipMapCount = MAX_MIPMAP);
374
-
375
-        ///@}
376
-
377
-
378
-        /**
379
-         * Convert bitmap to another type
380
-         * conversion to rgba always work. No-op if already rgba.
381
-         * \param type new type for the bitmap
382
-         * \return true if conversion succeeded, false else
383
-         */
384
-        bool convertToType (TType type);
385
-
386
-
387
-
388
-        /**
389
-         * Return the format of pixels stored at the present time in the object buffer.
390
-         * \return Pixel format (rgba luminance alpha alphaLuminance dxtc1 dxtc1Alpha dxtc3 dxtc5)
391
-         */
392
-        TType getPixelFormat() const
393
-        {
394
-                return PixelFormat;
395
-        }
396
-
397
-
398
-        /**
399
-         * Return the image width, or a mipmap width.
400
-         * \param mipMap mipmap level
401
-         * \return image width (0 if mipmap not found)
402
-         */
403
-        virtual uint32 getWidth(uint32 numMipMap = 0) const;
404
-
405
-
406
-        /**
407
-         * Return the image height, or a mipmap height.
408
-         * \param mipMap mipmap level
409
-         * \return image height (0 if mipmap not found)
410
-         */
411
-        virtual uint32 getHeight(uint32 numMipMap = 0) const;
412
-
413
-
414
-        /**
415
-         * Return the size (in pixels) of the image: <=> getHeight()*getWidth().
416
-         * \param mipMap mipmap level
417
-         * \return image size (0 if mipmap not found)
418
-         */
419
-        uint32 getSize(uint32 numMipMap = 0) const;
420
-
421
-
422
-        /**
423
-         * Return the number of mipmaps. Level0 is a mipmap...
424
-         * \return number of mipmaps. 0 if no image at all. 1 if no mipmaping (for the base level).
425
-         */
426
-        uint32 getMipMapCount() const
427
-        {
428
-                return _MipMapCount;
429
-        }
430
-
431
-        // Compute the number of mipmap needed for that bitmap (independently from the current number of mipmaps that have been set)
432
-        uint32 computeNeededMipMapCount() const;
433
-
434
-        /**
435
-         * Rotate a bitmap in CCW mode.
436
-         *
437
-         * \see releaseMipMaps().
438
-         */
439
-        void rotateCCW();
440
-
441
-        /**
442
-         * Build the mipmaps of the bitmap if they don't exist.
443
-         * Work only in RGBA mode...
444
-         * \see releaseMipMaps().
445
-         */
446
-        void buildMipMaps();
447
-
448
-        /**
449
-         * Release the mipmaps of the bitmap if they exist.
450
-         * Work for any mode.
451
-         * \see buildMipMaps().
452
-         */
453
-        void releaseMipMaps();
454
-
455
-        /**
456
-         * Reset the buffer. Mipmaps are deleted and bitmap is not valid anymore.
457
-         *
458
-         * \param type is the new type used for this texture
459
-         */
460
-        void reset(TType type=RGBA);
461
-
462
-
463
-        /**
464
-         * Resample the bitmap. If mipmaps exist they are deleted, then rebuilt
465
-         * after resampling.
466
-         * \param nNewWidth width after resample
467
-         * \param nNewHeight height after resample
468
-         */
469
-        void resample (sint32 nNewWidth, sint32 nNewHeight);
470
-
471
-
472
-        /**
473
-         * Resize the bitmap. If mipmaps exist they are deleted and not rebuilt.
474
-         * This is not a crop. Pixels are lost after resize.
475
-         *
476
-         * \param nNewWidth width after resize
477
-         * \param nNewHeight height after resize
478
-         * \param newType is the new type of the bitmap. If don_t_know, keep the same pixel format that before.
479
-         * \param resetTo0 by default the vector are filled by 0. set false to gain performances.
480
-         */
481
-        void resize (sint32 nNewWidth, sint32 nNewHeight, TType newType=DonTKnow, bool resetTo0= true);
482
-
483
-
484
-        /**  ADVANCED USE
485
-         * Resize a single mipmap level. resize() should have been called before.
486
-         * This is not a crop. Pixels are lost after resize.
487
-         *        No validity check is made. It is the user responsabitility fo setup correct mipmap size.
488
-         *
489
-         * \param numMipMap id of the mipmap
490
-         * \param nNewWidth width after resize
491
-         * \param nNewHeight height after resize
492
-         * \param resetTo0 by default the vector are filled by 0. set false to gain performances.
493
-         */
494
-        void resizeMipMap (uint32 numMipMap, sint32 nNewWidth, sint32 nNewHeight, bool resetTo0= true);
495
-
496
-
497
-        /**  ADVANCED USE
498
-         *        To use in conjunction with resizeMipMap. Setup the correct total number of mipmap
499
-         *        No validity check is made. It is the user responsabitility fo setup correct mipmap count.
500
-         */
501
-        void setMipMapCount(uint32 mmc);
502
-
503
-
504
-        /**
505
-         * Write a TGA (24 or 32 bits) from the object pixels buffer.
506
-         * If the current pixel format is not rgba then the method does nothing
507
-         * If the pixel format is Alpha then we save in 8 bpp
508
-         * \param f IStream (must be a reading stream)
509
-         * \param d depth : 8 or 16 or 24 or 32 (0 for automatic)
510
-         * \param upsideDown if true, the bitmap will be saved with the upside down
511
-         * \return true if succeed, false else
512
-         */
513
-        bool writeTGA(NLMISC::IStream &f, uint32 d=0, bool upsideDown = false);
514
-
515
-        /**
516
-         * Write a PNG (24 or 32 bits) from the object pixels buffer.
517
-         * If the current pixel format is not rgba then the method does nothing
518
-         * If the pixel format is Alpha then we save in 8 bpp
519
-         * \param f IStream (must be a reading stream)
520
-         * \param d depth : 8 or 16 or 24 or 32 (0 for automatic)
521
-         * \return true if succeed, false else
522
-         */
523
-        bool writePNG(NLMISC::IStream &f, uint32 d=0);
524
-
525
-        /**
526
-         * Write a JPG from the object pixels buffer.
527
-         * If the current pixel format is not rgba then the method does nothing
528
-         * If the pixel format is Alpha then we save in 8 bpp
529
-         * \param f IStream (must be a reading stream)
530
-         * \param quality 0=very bad quality 100=best quality
531
-         * \return true if succeed, false else
532
-         */
533
-        bool writeJPG(NLMISC::IStream &f, uint8 quality = 80);
534
-
535
-        /**
536
-         * Tell the bitmap to load grayscale bitmap as alpha or luminance format.
537
-         *
538
-         * \param loadAsAlpha is true to load grayscale bitmaps as alpha. false to load grayscale bitmaps as luminance.
539
-         * default value is true.
540
-         */
541
-        void loadGrayscaleAsAlpha (bool loadAsAlpha)
542
-        {
543
-                _LoadGrayscaleAsAlpha=loadAsAlpha;
544
-        }
545
-
546
-
547
-        /**
548
-         * Tell if the bitmap loads grayscale bitmap as alpha or luminance format.
549
-         *
550
-         * \return true if the bitmap loads grayscale bitmaps as alpha, false if it loads grayscale bitmaps as luminance.
551
-         */
552
-        bool isGrayscaleAsAlpha () const
553
-        {
554
-                return _LoadGrayscaleAsAlpha;
555
-        }
556
-
557
-
558
-        /**
559
-         * Perform a simple blit from the source to this bitmap at the (x, y) pos
560
-         * The dimension of the original bitmap are preserved
561
-         * For now, this texture and the source must have the same format
562
-         * With DXTC format, the dest coordinates must be a multiple of 4
563
-         * mipmap are not rebuild when present
564
-         * IMPORTANT : copy to self is not handled correctly
565
-         * \return true if the params were corrects and if the blit occurs. In debug build there's an assertion
566
-         */
567
-        bool blit(const CBitmap *src, sint32 x, sint32 y) ;
568
-        /**
569
-         * Extended version of blit. The destinaion of the blit is 'this' bitmap
570
-         * Source and dest rect are clamped as necessary.
571
-         * For now, only RGBA is uspported (an asertion occurs otherwise)
572
-         * mipmap are not updated.
573
-         * IMPORTANT : copy to self is not handled correctly
574
-         */
575
-        void blit(const CBitmap &src, sint srcX, sint srcY, sint srcWidth, sint srcHeight, sint destX, sint destY);
576
-
577
-
578
-        /**
579
-         * Get the color in the bitmap for the first mipmap
580
-         * The mipmaps must be built. If not just return the bilinear at the given point.
581
-         * NB: coordinates are clamped.
582
-         * \param tiled If false coordinate are clamped, else the bitmap is considered to tile
583
-         */
584
-        CRGBAF getColor (float x, float y) const;
585
-        // Get Color with optional tiling on axis
586
-        CRGBAF getColor (float x, float y, bool tileU, bool tileV) const;
587
-
588
-
589
-
590
-
591
-
592
-        /** Get the pixel at the given coorrdinate.
593
-          * Works in RGBA and DXTC modes.
594
-          * Outside of the bitmap it returns Black (or if mipmap is not found)
595
-          */
596
-        CRGBA  getPixelColor(sint x, sint y, uint32 numMipMap = 0) const;
597
-        /**
598
-         * Horizontal flip (all the columns are flipped)
599
-         * Works only with RGBA, and DXTC formats (only if w/h is a power of 2)
600
-         */
601
-        void flipH();
602
-
603
-
604
-        /**
605
-         * Vertical flip (all the rows are flipped)
606
-         * Works only with RGBA, and DXTC formats (only if w/h is a power of 2)
607
-         */
608
-        void flipV();
609
-
610
-        /**
611
-         * Rotation of the bitmap of 90 degree in clockwise
612
-         */
613
-        void rot90CW();
614
-
615
-        /**
616
-         * Rotation of the bitmap of 90 degree in counter clockwise
617
-         */
618
-        void rot90CCW();
619
-
620
-        /** Set this bitmap as the result of the blend bewteen 2 bitmap
621
-          * REQUIRE : - Bm0 and Bm1 should have the same size.
622
-          *           - Both bitmap should be convertible to RGBA pixel format.
623
-          * The result is a RGBA bitmap.
624
-          * NB: this just works with the first mipmaps
625
-          * \param factor The blend factor. 0 means the result is equal to Bm0, 256 means the result is equal to Bm1
626
-          * \param inputBitmapIsMutable when true, bitmap can be converted in place when needed (no copy done)
627
-          */
628
-        void blend(CBitmap &Bm0, CBitmap &Bm1, uint16 factor, bool inputBitmapIsMutable = false);
629
-
630
-        void getData(uint8*& extractData);
631
-
632
-        void getDibData(uint8*& extractData);
633
-
634
-        CBitmap& operator= (const CBitmap& from)
635
-        {
636
-                if (&from == this)
637
-                        return *this;
638
-                for (uint i=0; i!=MAX_MIPMAP; ++i)
639
-                {
640
-                        _Data[i] = from._Data[i]; // requires more than a surface copy
641
-                }
642
-                _MipMapCount = from._MipMapCount;
643
-                _LoadGrayscaleAsAlpha = from._LoadGrayscaleAsAlpha;
644
-                _Width = from._Width;
645
-                _Height = from._Height;
646
-                PixelFormat = from.PixelFormat;
647
-                return *this;
648
-        }
649
-};
650
-
651
-} // NLMISC
652
-
653
-
654
-#endif // NL_BITMAP_H
655
-
656
-/* End of bitmap.h */
657
+// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
658
+// Copyright (C) 2010  Winch Gate Property Limited
659
+//
660
+// This program is free software: you can redistribute it and/or modify
661
+// it under the terms of the GNU Affero General Public License as
662
+// published by the Free Software Foundation, either version 3 of the
663
+// License, or (at your option) any later version.
664
+//
665
+// This program is distributed in the hope that it will be useful,
666
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
667
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
668
+// GNU Affero General Public License for more details.
669
+//
670
+// You should have received a copy of the GNU Affero General Public License
671
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
672
+
673
+
674
+#ifndef NL_BITMAP_H
675
+#define NL_BITMAP_H
676
+
677
+
678
+#include "types_nl.h"
679
+#include "rgba.h"
680
+#include "debug.h"
681
+#include <vector>
682
+#include "object_vector.h"
683
+
684
+
685
+namespace NLMISC
686
+{
687
+
688
+
689
+class IStream;
690
+
691
+//------------------ DDS STUFFS --------------------
692
+
693
+#define NL_MAKEFOURCC(ch0, ch1, ch2, ch3) \
694
+        ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
695
+        ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
696
+
697
+const uint32        DDS_HEADER = NL_MAKEFOURCC('D', 'D', 'S', ' ');
698
+const uint32        DXT_HEADER = NL_MAKEFOURCC('D', 'X', 'T', '\0');
699
+const uint32        PNG_HEADER = NL_MAKEFOURCC(0x89, 'P', 'N', 'G');
700
+const uint32        JPG_HEADER = NL_MAKEFOURCC(0xff, 0xd8, 0xff, 0xe0);
701
+
702
+
703
+// dwLinearSize is valid
704
+        #define DDSD_LINEARSIZE         0x00080000l
705
+        
706
+//---------------- END OF DDS STUFFS ------------------
707
+
708
+
709
+const uint8        MAX_MIPMAP = 16;
710
+
711
+
712
+
713
+
714
+/**
715
+ * Class Bitmap
716
+ *
717
+ * \author Stephane Coutelas
718
+ * \author Nevrax France
719
+ * \date 2000
720
+ */
721
+/* *** IMPORTANT ********************
722
+ * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL
723
+ * **********************************
724
+ */
725
+class CBitmap
726
+{
727
+protected :
728
+        CObjectVector<uint8> _Data[MAX_MIPMAP];
729
+
730
+        // The number of mipmaps. base image IS a mipmap. 1 means a base image with no mipmaping.
731
+        uint8        _MipMapCount;
732
+        bool        _LoadGrayscaleAsAlpha;
733
+        uint32        _Width;
734
+        uint32        _Height;
735
+
736
+        // don't forget to update operator=() and swap() if adding a data member
737
+
738
+private :
739
+
740
+
741
+        /**
742
+         * blend 2 integers between 0 and 255 .
743
+         * \param n0 first integer
744
+         * \param n1 second integer
745
+         * \param coef coefficient for the first integer (must be in [0,256])
746
+         */
747
+        uint32 blend(uint32 &n0, uint32 &n1, uint32 coef0);
748
+
749
+
750
+        /**
751
+         * Read a DDS from an IStream.
752
+         * The bitmap is readen as a set of bytes and stocked compressed.
753
+         * Width and Height are multiple of 4.
754
+         * \param IStream The stream must be in reading mode.
755
+         * \return image depth
756
+         * \throw EDDSBadHeader : surface is header is not valid.
757
+         */
758
+        uint8 readDDS(NLMISC::IStream &f, uint mipMapSkip);
759
+
760
+
761
+        /**
762
+         * Read a TGA from an IStream.
763
+         * TGA pictures can be in 24 or 32 bits, RLE or uncompressed
764
+         * \param f IStream (must be a reading stream)
765
+         * \return image depth if succeed, 0 else
766
+         */
767
+        uint8 readTGA(        NLMISC::IStream &f);
768
+
769
+
770
+        /**
771
+         * Read a PNG from an IStream.
772
+         * PNG pictures can be in 24 or 32 bits
773
+         * \param f IStream (must be a reading stream)
774
+         * \return image depth if succeed, 0 else
775
+         */
776
+        uint8 readPNG( NLMISC::IStream &f );
777
+
778
+
779
+        /**
780
+         * Read a JPG from an IStream.
781
+         * JPG pictures can be in 24
782
+         * \param f IStream (must be a reading stream)
783
+         * \return image depth if succeed, 0 else
784
+         */
785
+        uint8 readJPG( NLMISC::IStream &f );
786
+
787
+
788
+        /**
789
+         * Change bitmap format
790
+         *
791
+         * about DXTC1 to DXTC5 :
792
+         * Does nothing if the format is not DXTC1
793
+         * about alpha encoding :
794
+         *                alpha0 == alpha1
795
+         *                code(x,y) == 7 for every (x,y)
796
+         *
797
+         * about luminance to alpha and alpha to luminance :
798
+         *      the buffer keeps unchanged
799
+         *
800
+         */
801
+        ///@{
802
+        bool convertToDXTC5();
803
+
804
+        bool convertToRGBA();
805
+        bool luminanceToRGBA();
806
+        bool alphaToRGBA();
807
+        bool alphaLuminanceToRGBA();
808
+
809
+        bool convertToLuminance();
810
+        bool rgbaToLuminance();
811
+        bool alphaToLuminance();
812
+        bool alphaLuminanceToLuminance();
813
+
814
+        bool convertToAlpha();
815
+        bool rgbaToAlpha();
816
+        bool luminanceToAlpha();
817
+        bool alphaLuminanceToAlpha();
818
+
819
+        bool convertToAlphaLuminance();
820
+        bool rgbaToAlphaLuminance();
821
+        bool luminanceToAlphaLuminance();
822
+        bool alphaToAlphaLuminance();
823
+
824
+        ///@}
825
+
826
+        /**
827
+         * Decompress bitmap compressed with S3TC DXT1 algorithm.
828
+         * \param alpha if alpha is true there's alpha.
829
+         */
830
+        bool decompressDXT1(bool alpha);
831
+
832
+        /**
833
+         * Decompress bitmap compressed with S3TC DXT3 algorithm.
834
+         * \throw EAllocationFailure : can't allocate memory.
835
+         */
836
+        bool decompressDXT3();
837
+
838
+
839
+        /**
840
+         * Decompress bitmap compressed with S3TC DXT3 algorithm.
841
+         * \throw EAllocationFailure : can't allocate memory.
842
+         */
843
+        bool decompressDXT5();
844
+
845
+
846
+        /**
847
+         * Extracting RGBA infos from a 16bits word. (used by S3TC decompression)
848
+         * \param color a 16bits integer
849
+         * \param r a CRGBA
850
+         */
851
+        static void uncompress(uint16 color, NLMISC::CRGBA &);
852
+
853
+
854
+        /**
855
+         * The resample function
856
+         * \param pSrc CRGBA array
857
+         * \param pDest CRGBA array for storing resampled texture
858
+         * \param nSrcWidth original width
859
+         * \param nSrcHeight original height
860
+         * \param nDestWidth width after resample
861
+         * \param nDestHeight height after resample
862
+         */
863
+        void resamplePicture32 (const NLMISC::CRGBA *pSrc, NLMISC::CRGBA *pDest,
864
+                                                         sint32 nSrcWidth, sint32 nSrcHeight,
865
+                                                         sint32 nDestWidth, sint32 nDestHeight);
866
+
867
+        /**
868
+         * The FAST resample function : works only when reducing the size by two
869
+         * and when the image is square
870
+         * \param pSrc CRGBA array
871
+         * \param pDest CRGBA array for storing resampled texture
872
+         * \param nSrcWidth original width
873
+         * \param nSrcHeight original height
874
+         * \param nDestWidth width after resample
875
+         * \param nDestHeight height after resample
876
+         */
877
+        void resamplePicture32Fast (const NLMISC::CRGBA *pSrc, NLMISC::CRGBA *pDest,
878
+                                                                sint32 nSrcWidth, sint32 nSrcHeight,
879
+                                                                sint32 nDestWidth, sint32 nDestHeight);
880
+
881
+
882
+        /**
883
+         * Quadratic interpolator
884
+         * \return the interpolation in (x,y) of the values (xy**)
885
+         */
886
+        float getColorInterp (float x, float y, float xy00, float xy01, float xy10, float xy11) const;
887
+
888
+
889
+        /// name  DXTC single texel read
890
+        //@{
891
+                static CRGBA getDXTCColorFromBlock(const uint8 *block, sint x, sint y);
892
+                CRGBA getDXTC1Texel(sint x, sint y, uint32 numMipMap) const;
893
+                CRGBA getDXTC3Texel(sint x, sint y, uint32 numMipMap) const;
894
+                CRGBA getDXTC5Texel(sint x, sint y, uint32 numMipMap) const;
895
+        //@}
896
+
897
+
898
+        CRGBA getRGBAPixel(sint x, sint y, uint32 numMipMap /*=0*/) const;
899
+
900
+
901
+        // Make a dummy from a bitfield
902
+        void        makeDummyFromBitField(const uint8        bitmap[1024]);
903
+
904
+        // Flip DXTC
905
+        void        flipHDXTCBlockColor(uint8 *bitColor, uint32 w);
906
+        void        flipVDXTCBlockColor(uint8 *bitColor, uint32 h);
907
+        void        flipHDXTCBlockAlpha3(uint8 *bitColor, uint32 w);
908
+        void        flipVDXTCBlockAlpha3(uint8 *bitColor, uint32 h);
909
+        void        flipHDXTCBlockAlpha5(uint8 *bitColor, uint32 w);
910
+        void        flipVDXTCBlockAlpha5(uint8 *bitColor, uint32 h);
911
+        void        flipDXTC(bool vertical);
912
+        void        flipDXTCMipMap(bool vertical, uint mm, uint type);
913
+
914
+public:
915
+
916
+        enum TType
917
+        {
918
+                RGBA=0,
919
+                Luminance,
920
+                Alpha,
921
+                AlphaLuminance,
922
+                DXTC1,
923
+                DXTC1Alpha,
924
+                DXTC3,
925
+                DXTC5,
926
+                DsDt,
927
+                ModeCount,
928
+                DonTKnow=0xffffffff
929
+        } PixelFormat;
930
+
931
+        static const uint32 bitPerPixels[ModeCount];
932
+        static const uint32 DXTC1HEADER;
933
+        static const uint32 DXTC3HEADER;
934
+        static const uint32 DXTC5HEADER;
935
+
936
+        // don't forget to update operator=() and swap() if adding a data member
937
+
938
+        CBitmap()
939
+        {
940
+                _MipMapCount = 1;
941
+                _Width = 0;
942
+                _Height = 0;
943
+                PixelFormat = RGBA;
944
+                _LoadGrayscaleAsAlpha = true;
945
+        }
946
+
947
+        virtual ~CBitmap() { }
948
+
949
+        // swap 2 bitmaps contents
950
+        void        swap(CBitmap &other);
951
+
952
+        /**
953
+         * Read a bitmap(TGA or DDS) from an IStream.
954
+         * Bitmap supported are DDS (DXTC1, DXTC1 with Alpha, DXTC3, DXTC5, and
955
+         * uncompressed TGA (24 and 32 bits).
956
+         * \param IStream The stream must be in reading mode.
957
+         * \param mipMapSkip if the file is a DDS with mipMap. N=mipMapSkip mipmaps are skipped.
958
+         * \return image depth (24 or 32), or 0 if load failed
959
+         * \throw ESeekFailed : seek has failed
960
+         */
961
+        uint8        load(NLMISC::IStream &f, uint mipMapSkip=0);
962
+
963
+
964
+        /**
965
+         * Determinate the bitmap size from a bitmap(TGA or DDS) from an IStream. load just header of the file.
966
+         * Bitmap supported are DDS (DXTC1, DXTC1 with Alpha, DXTC3, DXTC5, and
967
+         * uncompressed TGA (24 and 32 bits).
968
+         * NB: at the end, f is seeked to begin.
969
+         * \param IStream The stream must be in reading mode.
970
+         * \param width the width of the image. 0 if fails.
971
+         * \param height the height of the image. 0 if fails.
972
+         * \throw ESeekFailed : seek has failed
973
+         */
974
+        static void                loadSize(NLMISC::IStream &f, uint32 &width, uint32 &height);
975
+
976
+
977
+        /** same than other loadSize(), but with a pathName.
978
+         * \see loadSize()
979
+         */
980
+        static void                loadSize(const std::string &path, uint32 &retWidth, uint32 &retHeight);
981
+
982
+
983
+        /**
984
+         * Make a dummy "?" texture. Useful for file not found. Mode is rgba.
985
+         */
986
+        void        makeDummy();
987
+
988
+
989
+        /**
990
+         * Make a dummy "2" texture. Useful for file not power of 2. Mode is rgba.
991
+         */
992
+        void        makeNonPowerOf2Dummy();
993
+
994
+        /**
995
+         * Return the pixels buffer of the image, or of one of its mipmap.
996
+         * Return a reference of an array in pixel format get with getPixelFormat().
997
+         * \return CObjectVector<uint8>& RGBA pixels
998
+         */
999
+        ///@{
1000
+        CObjectVector<uint8>& getPixels(uint32 numMipMap = 0)
1001
+        {
1002
+                //nlassert (numMipMap<=_MipMapCount);
1003
+                return _Data[numMipMap];
1004
+        }
1005
+        const CObjectVector<uint8>& getPixels(uint32 numMipMap = 0) const
1006
+        {
1007
+                //nlassert (numMipMap<=_MipMapCount);
1008
+                return _Data[numMipMap];
1009
+        }
1010
+        /** Gain ownership of this texture datas. As a result, the bitmap is reseted (put in the same state than when ctor is called, e.g a single mipmap with null size)
1011
+          * The CObjectVector objects that contains the bitmap (one per mipmap) datas are 'swapped' with those in the array  provided by the caller.
1012
+          * NB : The user must provide at least min(getMipMapCount(), maxMipMapCount) entries in the array
1013
+          * \param mipmapArray Array of mipmap that receive the bitmap datas
1014
+          * \param maxMipMapCount Max number of mipmap to be copied in the destination array.
1015
+          */
1016
+        void unattachPixels(CObjectVector<uint8> *mipmapDestArray, uint maxMipMapCount = MAX_MIPMAP);
1017
+
1018
+        ///@}
1019
+
1020
+
1021
+        /**
1022
+         * Convert bitmap to another type
1023
+         * conversion to rgba always work. No-op if already rgba.
1024
+         * \param type new type for the bitmap
1025
+         * \return true if conversion succeeded, false else
1026
+         */
1027
+        bool convertToType (TType type);
1028
+
1029
+
1030
+
1031
+        /**
1032
+         * Return the format of pixels stored at the present time in the object buffer.
1033
+         * \return Pixel format (rgba luminance alpha alphaLuminance dxtc1 dxtc1Alpha dxtc3 dxtc5)
1034
+         */
1035
+        TType getPixelFormat() const
1036
+        {
1037
+                return PixelFormat;
1038
+        }
1039
+
1040
+
1041
+        /**
1042
+         * Return the image width, or a mipmap width.
1043
+         * \param mipMap mipmap level
1044
+         * \return image width (0 if mipmap not found)
1045
+         */
1046
+        virtual uint32 getWidth(uint32 numMipMap = 0) const;
1047
+
1048
+
1049
+        /**
1050
+         * Return the image height, or a mipmap height.
1051
+         * \param mipMap mipmap level
1052
+         * \return image height (0 if mipmap not found)
1053
+         */
1054
+        virtual uint32 getHeight(uint32 numMipMap = 0) const;
1055
+
1056
+
1057
+        /**
1058
+         * Return the size (in pixels) of the image: <=> getHeight()*getWidth().
1059
+         * \param mipMap mipmap level
1060
+         * \return image size (0 if mipmap not found)
1061
+         */
1062
+        uint32 getSize(uint32 numMipMap = 0) const;
1063
+
1064
+
1065
+        /**
1066
+         * Return the number of mipmaps. Level0 is a mipmap...
1067
+         * \return number of mipmaps. 0 if no image at all. 1 if no mipmaping (for the base level).
1068
+         */
1069
+        uint32 getMipMapCount() const
1070
+        {
1071
+                return _MipMapCount;
1072
+        }
1073
+
1074
+        // Compute the number of mipmap needed for that bitmap (independently from the current number of mipmaps that have been set)
1075
+        uint32 computeNeededMipMapCount() const;
1076
+
1077
+        /**
1078
+         * Rotate a bitmap in CCW mode.
1079
+         *
1080
+         * \see releaseMipMaps().
1081
+         */
1082
+        void rotateCCW();
1083
+
1084
+        /**
1085
+         * Build the mipmaps of the bitmap if they don't exist.
1086
+         * Work only in RGBA mode...
1087
+         * \see releaseMipMaps().
1088
+         */
1089
+        void buildMipMaps();
1090
+
1091
+        /**
1092
+         * Release the mipmaps of the bitmap if they exist.
1093
+         * Work for any mode.
1094
+         * \see buildMipMaps().
1095
+         */
1096
+        void releaseMipMaps();
1097
+
1098
+        /**
1099
+         * Reset the buffer. Mipmaps are deleted and bitmap is not valid anymore.
1100
+         *
1101
+         * \param type is the new type used for this texture
1102
+         */
1103
+        void reset(TType type=RGBA);
1104
+
1105
+
1106
+        /**
1107
+         * Resample the bitmap. If mipmaps exist they are deleted, then rebuilt
1108
+         * after resampling.
1109
+         * \param nNewWidth width after resample
1110
+         * \param nNewHeight height after resample
1111
+         */
1112
+        void resample (sint32 nNewWidth, sint32 nNewHeight);
1113
+
1114
+
1115
+        /**
1116
+         * Resize the bitmap. If mipmaps exist they are deleted and not rebuilt.
1117
+         * This is not a crop. Pixels are lost after resize.
1118
+         *
1119
+         * \param nNewWidth width after resize
1120
+         * \param nNewHeight height after resize
1121
+         * \param newType is the new type of the bitmap. If don_t_know, keep the same pixel format that before.
1122
+         * \param resetTo0 by default the vector are filled by 0. set false to gain performances.
1123
+         */
1124
+        void resize (sint32 nNewWidth, sint32 nNewHeight, TType newType=DonTKnow, bool resetTo0= true);
1125
+
1126
+
1127
+        /**  ADVANCED USE
1128
+         * Resize a single mipmap level. resize() should have been called before.
1129
+         * This is not a crop. Pixels are lost after resize.
1130
+         *        No validity check is made. It is the user responsabitility fo setup correct mipmap size.
1131
+         *
1132
+         * \param numMipMap id of the mipmap
1133
+         * \param nNewWidth width after resize
1134
+         * \param nNewHeight height after resize
1135
+         * \param resetTo0 by default the vector are filled by 0. set false to gain performances.
1136
+         */
1137
+        void resizeMipMap (uint32 numMipMap, sint32 nNewWidth, sint32 nNewHeight, bool resetTo0= true);
1138
+
1139
+
1140
+        /**  ADVANCED USE
1141
+         *        To use in conjunction with resizeMipMap. Setup the correct total number of mipmap
1142
+         *        No validity check is made. It is the user responsabitility fo setup correct mipmap count.
1143
+         */
1144
+        void setMipMapCount(uint32 mmc);
1145
+
1146
+
1147
+        /**
1148
+         * Write a TGA (24 or 32 bits) from the object pixels buffer.
1149
+         * If the current pixel format is not rgba then the method does nothing
1150
+         * If the pixel format is Alpha then we save in 8 bpp
1151
+         * \param f IStream (must be a reading stream)
1152
+         * \param d depth : 8 or 16 or 24 or 32 (0 for automatic)
1153
+         * \param upsideDown if true, the bitmap will be saved with the upside down
1154
+         * \return true if succeed, false else
1155
+         */
1156
+        bool writeTGA(NLMISC::IStream &f, uint32 d=0, bool upsideDown = false);
1157
+
1158
+        /**
1159
+         * Write a PNG (24 or 32 bits) from the object pixels buffer.
1160
+         * If the current pixel format is not rgba then the method does nothing
1161
+         * If the pixel format is Alpha then we save in 8 bpp
1162
+         * \param f IStream (must be a reading stream)
1163
+         * \param d depth : 8 or 16 or 24 or 32 (0 for automatic)
1164
+         * \return true if succeed, false else
1165
+         */
1166
+        bool writePNG(NLMISC::IStream &f, uint32 d=0);
1167
+
1168
+        /**
1169
+         * Write a JPG from the object pixels buffer.
1170
+         * If the current pixel format is not rgba then the method does nothing
1171
+         * If the pixel format is Alpha then we save in 8 bpp
1172
+         * \param f IStream (must be a reading stream)
1173
+         * \param quality 0=very bad quality 100=best quality
1174
+         * \return true if succeed, false else
1175
+         */
1176
+        bool writeJPG(NLMISC::IStream &f, uint8 quality = 80);
1177
+
1178
+        /**
1179
+         * Tell the bitmap to load grayscale bitmap as alpha or luminance format.
1180
+         *
1181
+         * \param loadAsAlpha is true to load grayscale bitmaps as alpha. false to load grayscale bitmaps as luminance.
1182
+         * default value is true.
1183
+         */
1184
+        void loadGrayscaleAsAlpha (bool loadAsAlpha)
1185
+        {
1186
+                _LoadGrayscaleAsAlpha=loadAsAlpha;
1187
+        }
1188
+
1189
+
1190
+        /**
1191
+         * Tell if the bitmap loads grayscale bitmap as alpha or luminance format.
1192
+         *
1193
+         * \return true if the bitmap loads grayscale bitmaps as alpha, false if it loads grayscale bitmaps as luminance.
1194
+         */
1195
+        bool isGrayscaleAsAlpha () const
1196
+        {
1197
+                return _LoadGrayscaleAsAlpha;
1198
+        }
1199
+
1200
+
1201
+        /**
1202
+         * Perform a simple blit from the source to this bitmap at the (x, y) pos
1203
+         * The dimension of the original bitmap are preserved
1204
+         * For now, this texture and the source must have the same format
1205
+         * With DXTC format, the dest coordinates must be a multiple of 4
1206
+         * mipmap are not rebuild when present
1207
+         * IMPORTANT : copy to self is not handled correctly
1208
+         * \return true if the params were corrects and if the blit occurs. In debug build there's an assertion
1209
+         */
1210
+        bool blit(const CBitmap *src, sint32 x, sint32 y) ;
1211
+        /**
1212
+         * Extended version of blit. The destinaion of the blit is 'this' bitmap
1213
+         * Source and dest rect are clamped as necessary.
1214
+         * For now, only RGBA is uspported (an asertion occurs otherwise)
1215
+         * mipmap are not updated.
1216
+         * IMPORTANT : copy to self is not handled correctly
1217
+         */
1218
+        void blit(const CBitmap &src, sint srcX, sint srcY, sint srcWidth, sint srcHeight, sint destX, sint destY);
1219
+
1220
+
1221
+        /**
1222
+         * Get the color in the bitmap for the first mipmap
1223
+         * The mipmaps must be built. If not just return the bilinear at the given point.
1224
+         * NB: coordinates are clamped.
1225
+         * \param tiled If false coordinate are clamped, else the bitmap is considered to tile
1226
+         */
1227
+        CRGBAF getColor (float x, float y) const;
1228
+        // Get Color with optional tiling on axis
1229
+        CRGBAF getColor (float x, float y, bool tileU, bool tileV) const;
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+        /** Get the pixel at the given coorrdinate.
1236
+          * Works in RGBA and DXTC modes.
1237
+          * Outside of the bitmap it returns Black (or if mipmap is not found)
1238
+          */
1239
+        CRGBA  getPixelColor(sint x, sint y, uint32 numMipMap = 0) const;
1240
+        /**
1241
+         * Horizontal flip (all the columns are flipped)
1242
+         * Works only with RGBA, and DXTC formats (only if w/h is a power of 2)
1243
+         */
1244
+        void flipH();
1245
+
1246
+
1247
+        /**
1248
+         * Vertical flip (all the rows are flipped)
1249
+         * Works only with RGBA, and DXTC formats (only if w/h is a power of 2)
1250
+         */
1251
+        void flipV();
1252
+
1253
+        /**
1254
+         * Rotation of the bitmap of 90 degree in clockwise
1255
+         */
1256
+        void rot90CW();
1257
+
1258
+        /**
1259
+         * Rotation of the bitmap of 90 degree in counter clockwise
1260
+         */
1261
+        void rot90CCW();
1262
+
1263
+        /** Set this bitmap as the result of the blend bewteen 2 bitmap
1264
+          * REQUIRE : - Bm0 and Bm1 should have the same size.
1265
+          *           - Both bitmap should be convertible to RGBA pixel format.
1266
+          * The result is a RGBA bitmap.
1267
+          * NB: this just works with the first mipmaps
1268
+          * \param factor The blend factor. 0 means the result is equal to Bm0, 256 means the result is equal to Bm1
1269
+          * \param inputBitmapIsMutable when true, bitmap can be converted in place when needed (no copy done)
1270
+          */
1271
+        void blend(CBitmap &Bm0, CBitmap &Bm1, uint16 factor, bool inputBitmapIsMutable = false);
1272
+
1273
+        void getData(uint8*& extractData);
1274
+
1275
+        void getDibData(uint8*& extractData);
1276
+
1277
+        CBitmap& operator= (const CBitmap& from)
1278
+        {
1279
+                if (&from == this)
1280
+                        return *this;
1281
+                for (uint i=0; i!=MAX_MIPMAP; ++i)
1282
+                {
1283
+                        _Data[i] = from._Data[i]; // requires more than a surface copy
1284
+                }
1285
+                _MipMapCount = from._MipMapCount;
1286
+                _LoadGrayscaleAsAlpha = from._LoadGrayscaleAsAlpha;
1287
+                _Width = from._Width;
1288
+                _Height = from._Height;
1289
+                PixelFormat = from.PixelFormat;
1290
+                return *this;
1291
+        }
1292
+};
1293
+
1294
+} // NLMISC
1295
+
1296
+
1297
+#endif // NL_BITMAP_H
1298
+
1299
+/* End of bitmap.h */