Coverage Report

Created: 2025-12-02 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/Conversion.cpp
Line
Count
Source
1
// ==========================================================
2
// Bitmap conversion routines
3
//
4
// Design and implementation by
5
// - Floris van den Berg (flvdberg@wxs.nl)
6
// - Hervé Drolon (drolon@infonie.fr)
7
// - Jani Kajala (janik@remedy.fi)
8
// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
9
// - Carsten Klein (cklein05@users.sourceforge.net)
10
//
11
// This file is part of FreeImage 3
12
//
13
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
14
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
15
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
16
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
17
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
18
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
19
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
20
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
21
// THIS DISCLAIMER.
22
//
23
// Use at your own risk!
24
// ==========================================================
25
26
#include "FreeImage.h"
27
#include "Utilities.h"
28
#include "Quantizers.h"
29
30
// ----------------------------------------------------------
31
32
0
#define CONVERT(from, to) case to : FreeImage_ConvertLine##from##To##to(bits, scanline, FreeImage_GetWidth(dib)); break;
33
34
0
#define CONVERTWITHPALETTE(from, to) case to : FreeImage_ConvertLine##from##To##to(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); break;
35
36
0
#define CONVERTTO32WITHPALETTE(from) case 32 : \
37
0
    if (bIsTransparent) { \
38
0
        FreeImage_ConvertLine##from##To32MapTransparency(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib)); \
39
0
    } else { \
40
0
        FreeImage_ConvertLine##from##To32(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); \
41
0
    } \
42
0
    break;
43
44
#define CONVERTTO16(from) \
45
0
  case 16 : \
46
0
    if ((red_mask == FI16_555_RED_MASK) && (green_mask == FI16_555_GREEN_MASK) && (blue_mask == FI16_555_BLUE_MASK)) { \
47
0
      FreeImage_ConvertLine##from##To16_555(bits, scanline, FreeImage_GetWidth(dib)); \
48
0
    } else { \
49
0
      FreeImage_ConvertLine##from##To16_565(bits, scanline, FreeImage_GetWidth(dib)); \
50
0
    } \
51
0
    break;
52
53
#define CONVERTTO16WITHPALETTE(from) \
54
0
  case 16 : \
55
0
    if ((red_mask == FI16_555_RED_MASK) && (green_mask == FI16_555_GREEN_MASK) && (blue_mask == FI16_555_BLUE_MASK)) { \
56
0
      FreeImage_ConvertLine##from##To16_555(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); \
57
0
    } else { \
58
0
      FreeImage_ConvertLine##from##To16_565(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); \
59
0
    } \
60
0
    break;
61
62
// ==========================================================
63
// Utility functions declared in Utilities.h
64
65
0
BOOL SwapRedBlue32(FIBITMAP* dib) {
66
0
  if(FreeImage_GetImageType(dib) != FIT_BITMAP) {
67
0
    return FALSE;
68
0
  }
69
    
70
0
  const unsigned bytesperpixel = FreeImage_GetBPP(dib) / 8;
71
0
  if(bytesperpixel > 4 || bytesperpixel < 3) {
72
0
    return FALSE;
73
0
  }
74
    
75
0
  const unsigned height = FreeImage_GetHeight(dib);
76
0
  const unsigned pitch = FreeImage_GetPitch(dib);
77
0
  const unsigned lineSize = FreeImage_GetLine(dib);
78
  
79
0
  BYTE* line = FreeImage_GetBits(dib);
80
0
  for(unsigned y = 0; y < height; ++y, line += pitch) {
81
0
    for(BYTE* pixel = line; pixel < line + lineSize ; pixel += bytesperpixel) {
82
0
      INPLACESWAP(pixel[0], pixel[2]);
83
0
    }
84
0
  }
85
  
86
0
  return TRUE;
87
0
}
88
89
// ----------------------------------------------------------
90
91
static inline void 
92
0
assignRGB(WORD r, WORD g, WORD b, WORD* out) {
93
0
  out[0] = r;
94
0
  out[1] = g;
95
0
  out[2] = b;
96
0
}
97
98
static inline void 
99
0
assignRGB(BYTE r, BYTE g, BYTE b, BYTE* out) {
100
0
  out[FI_RGBA_RED] = r;
101
0
  out[FI_RGBA_GREEN] = g;
102
0
  out[FI_RGBA_BLUE] = b;
103
0
}
104
105
/**
106
CMYK -> CMY -> RGB conversion from http://www.easyrgb.com/
107
108
CMYK to CMY [0-1]: C,M,Y * (1 - K) + K
109
CMY to RGB [0-1]: (1 - C,M,Y)
110
111
=> R,G,B = (1 - C,M,Y) * (1 - K)
112
mapped to [0-MAX_VAL]: 
113
(MAX_VAL - C,M,Y) * (MAX_VAL - K) / MAX_VAL
114
*/
115
template <class T>
116
static inline void 
117
0
CMYKToRGB(T C, T M, T Y, T K, T* out) {
118
0
  unsigned max_val = std::numeric_limits<T>::max();
119
  
120
0
  unsigned r = (max_val - C) * (max_val - K) / max_val;
121
0
  unsigned g = (max_val - M) * (max_val - K) / max_val;
122
0
  unsigned b = (max_val - Y) * (max_val - K) / max_val;
123
124
  // clamp values to [0..max_val]
125
0
  T red = (T)CLAMP(r, (unsigned)0, max_val);
126
0
  T green = (T)CLAMP(g, (unsigned)0, max_val);
127
0
  T blue  = (T)CLAMP(b, (unsigned)0, max_val);
128
129
0
  assignRGB(red, green, blue, out);
130
0
}
Unexecuted instantiation: Conversion.cpp:void CMYKToRGB<unsigned short>(unsigned short, unsigned short, unsigned short, unsigned short, unsigned short*)
Unexecuted instantiation: Conversion.cpp:void CMYKToRGB<unsigned char>(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*)
131
132
template <class T>
133
static void 
134
0
_convertCMYKtoRGBA(unsigned width, unsigned height, BYTE* line_start, unsigned pitch, unsigned samplesperpixel) {
135
0
  const BOOL hasBlack = (samplesperpixel > 3) ? TRUE : FALSE;
136
0
  const T MAX_VAL = std::numeric_limits<T>::max();
137
    
138
0
  T K = 0;
139
0
  for(unsigned y = 0; y < height; y++) {
140
0
    T *line = (T*)line_start;
141
142
0
    for(unsigned x = 0; x < width; x++) {
143
0
      if(hasBlack) {
144
0
        K = line[FI_RGBA_ALPHA];      
145
0
        line[FI_RGBA_ALPHA] = MAX_VAL; // TODO write the first extra channel as alpha!
146
0
      }     
147
      
148
0
      CMYKToRGB<T>(line[0], line[1], line[2], K, line);
149
      
150
0
      line += samplesperpixel;
151
0
    }
152
0
    line_start += pitch;
153
0
  }
154
0
}
Unexecuted instantiation: Conversion.cpp:void _convertCMYKtoRGBA<unsigned short>(unsigned int, unsigned int, unsigned char*, unsigned int, unsigned int)
Unexecuted instantiation: Conversion.cpp:void _convertCMYKtoRGBA<unsigned char>(unsigned int, unsigned int, unsigned char*, unsigned int, unsigned int)
155
156
BOOL 
157
0
ConvertCMYKtoRGBA(FIBITMAP* dib) {
158
0
  if(!FreeImage_HasPixels(dib)) {
159
0
    return FALSE;
160
0
  }
161
    
162
0
  const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
163
0
  const unsigned bytesperpixel = FreeImage_GetBPP(dib)/8;
164
  
165
0
  unsigned channelSize = 1;
166
0
  if (image_type == FIT_RGBA16 || image_type == FIT_RGB16) {
167
0
    channelSize = sizeof(WORD);
168
0
  } else if (!(image_type == FIT_BITMAP && (bytesperpixel > 2))) {
169
0
    return FALSE;
170
0
  }
171
        
172
0
  const unsigned width = FreeImage_GetWidth(dib);
173
0
  const unsigned height = FreeImage_GetHeight(dib);
174
0
  BYTE *line_start = FreeImage_GetScanLine(dib, 0);
175
0
  const unsigned pitch = FreeImage_GetPitch(dib);
176
  
177
0
  unsigned samplesperpixel = FreeImage_GetLine(dib) / width / channelSize;
178
179
0
  if(channelSize == sizeof(WORD)) {
180
0
    _convertCMYKtoRGBA<WORD>(width, height, line_start, pitch, samplesperpixel);
181
0
  } else {
182
0
    _convertCMYKtoRGBA<BYTE>(width, height, line_start, pitch, samplesperpixel);
183
0
  }
184
185
0
  return TRUE; 
186
0
}
187
188
// ----------------------------------------------------------
189
190
/**
191
CIELab -> XYZ conversion from http://www.easyrgb.com/
192
*/
193
static void 
194
0
CIELabToXYZ(float L, float a, float b, float *X, float *Y, float *Z) {
195
0
  float pow_3;
196
  
197
  // CIELab -> XYZ conversion 
198
  // ------------------------
199
0
  float var_Y = (L + 16.F ) / 116.F;
200
0
  float var_X = a / 500.F + var_Y;
201
0
  float var_Z = var_Y - b / 200.F;
202
203
0
  pow_3 = powf(var_Y, 3);
204
0
  if(pow_3 > 0.008856F) {
205
0
    var_Y = pow_3;
206
0
  } else {
207
0
    var_Y = ( var_Y - 16.F / 116.F ) / 7.787F;
208
0
  }
209
0
  pow_3 = powf(var_X, 3);
210
0
  if(pow_3 > 0.008856F) {
211
0
    var_X = pow_3;
212
0
  } else {
213
0
    var_X = ( var_X - 16.F / 116.F ) / 7.787F;
214
0
  }
215
0
  pow_3 = powf(var_Z, 3);
216
0
  if(pow_3 > 0.008856F) {
217
0
    var_Z = pow_3;
218
0
  } else {
219
0
    var_Z = ( var_Z - 16.F / 116.F ) / 7.787F;
220
0
  }
221
222
0
  static const float ref_X =  95.047F;
223
0
  static const float ref_Y = 100.000F;
224
0
  static const float ref_Z = 108.883F;
225
226
0
  *X = ref_X * var_X; // ref_X = 95.047 (Observer= 2°, Illuminant= D65)
227
0
  *Y = ref_Y * var_Y; // ref_Y = 100.000
228
0
  *Z = ref_Z * var_Z; // ref_Z = 108.883
229
0
}
230
231
/**
232
XYZ -> RGB conversion from http://www.easyrgb.com/
233
*/
234
static void 
235
0
XYZToRGB(float X, float Y, float Z, float *R, float *G, float *B) {
236
0
  float var_X = X / 100; // X from 0 to  95.047 (Observer = 2°, Illuminant = D65)
237
0
  float var_Y = Y / 100; // Y from 0 to 100.000
238
0
  float var_Z = Z / 100; // Z from 0 to 108.883
239
240
0
  float var_R = var_X *  3.2406F + var_Y * -1.5372F + var_Z * -0.4986F;
241
0
  float var_G = var_X * -0.9689F + var_Y *  1.8758F + var_Z *  0.0415F;
242
0
  float var_B = var_X *  0.0557F + var_Y * -0.2040F + var_Z *  1.0570F;
243
244
0
  float exponent = 1.F / 2.4F;
245
246
0
  if(var_R > 0.0031308F) {
247
0
    var_R = 1.055F * powf(var_R, exponent) - 0.055F;
248
0
  } else {
249
0
    var_R = 12.92F * var_R;
250
0
  }
251
0
  if(var_G > 0.0031308F) {
252
0
    var_G = 1.055F * powf(var_G, exponent) - 0.055F;
253
0
  } else {
254
0
    var_G = 12.92F * var_G;
255
0
  }
256
0
  if(var_B > 0.0031308F) {
257
0
    var_B = 1.055F * powf(var_B, exponent) - 0.055F;
258
0
  } else {
259
0
    var_B = 12.92F * var_B;
260
0
  }
261
262
0
  *R = var_R;
263
0
  *G = var_G;
264
0
  *B = var_B;
265
0
}
266
267
template<class T>
268
static void 
269
0
CIELabToRGB(float L, float a, float b, T *rgb) {
270
0
  float X, Y, Z;
271
0
  float R, G, B;
272
0
  const float max_val = std::numeric_limits<T>::max();
273
274
0
  CIELabToXYZ(L, a, b, &X, &Y, &Z);
275
0
  XYZToRGB(X, Y, Z, &R, &G, &B);
276
  
277
  // clamp values to [0..max_val]
278
0
  T red = (T)CLAMP(R * max_val, 0.0F, max_val);
279
0
  T green = (T)CLAMP(G * max_val, 0.0F, max_val);
280
0
  T blue  = (T)CLAMP(B * max_val, 0.0F, max_val);
281
282
0
  assignRGB(red, green, blue, rgb);
283
0
}
Unexecuted instantiation: Conversion.cpp:void CIELabToRGB<unsigned char>(float, float, float, unsigned char*)
Unexecuted instantiation: Conversion.cpp:void CIELabToRGB<unsigned short>(float, float, float, unsigned short*)
284
285
template<class T>
286
static void 
287
0
_convertLABtoRGB(unsigned width, unsigned height, BYTE* line_start, unsigned pitch, unsigned samplesperpixel) {
288
0
  const unsigned max_val = std::numeric_limits<T>::max();
289
0
  const float sL = 100.F / max_val;
290
0
  const float sa = 256.F / max_val;
291
0
  const float sb = 256.F / max_val;
292
  
293
0
  for(unsigned y = 0; y < height; y++) {
294
0
    T *line = (T*)line_start;
295
296
0
    for(unsigned x = 0; x < width; x++) {
297
0
      CIELabToRGB(line[0]* sL, line[1]* sa - 128.F, line[2]* sb - 128.F, line);
298
      
299
0
      line += samplesperpixel;
300
0
    }
301
0
    line_start += pitch;
302
0
  }
303
0
}
Unexecuted instantiation: Conversion.cpp:void _convertLABtoRGB<unsigned char>(unsigned int, unsigned int, unsigned char*, unsigned int, unsigned int)
Unexecuted instantiation: Conversion.cpp:void _convertLABtoRGB<unsigned short>(unsigned int, unsigned int, unsigned char*, unsigned int, unsigned int)
304
305
BOOL
306
0
ConvertLABtoRGB(FIBITMAP* dib) {
307
0
  if(!FreeImage_HasPixels(dib)) {
308
0
    return FALSE;
309
0
  }
310
    
311
0
  const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
312
0
  const unsigned bytesperpixel = FreeImage_GetBPP(dib) / 8;
313
  
314
0
  unsigned channelSize = 1;
315
0
  if (image_type == FIT_RGBA16 || image_type == FIT_RGB16) {
316
0
    channelSize = sizeof(WORD);
317
0
  } else if (!(image_type == FIT_BITMAP && (bytesperpixel > 2))) {
318
0
    return FALSE;
319
0
  }
320
        
321
0
  const unsigned width = FreeImage_GetWidth(dib);
322
0
  const unsigned height = FreeImage_GetHeight(dib);
323
0
  BYTE *line_start = FreeImage_GetScanLine(dib, 0);
324
0
  const unsigned pitch = FreeImage_GetPitch(dib);
325
  
326
0
  unsigned samplesperpixel = FreeImage_GetLine(dib) / width / channelSize;
327
      
328
0
  if(channelSize == 1) {
329
0
    _convertLABtoRGB<BYTE>(width, height, line_start, pitch, samplesperpixel);
330
0
  }
331
0
  else {
332
0
    _convertLABtoRGB<WORD>(width, height, line_start, pitch, samplesperpixel);
333
0
  }
334
335
0
  return TRUE; 
336
0
}
337
338
// ----------------------------------------------------------
339
340
FIBITMAP* 
341
0
RemoveAlphaChannel(FIBITMAP* src) { 
342
343
0
  if(!FreeImage_HasPixels(src)) {
344
0
    return NULL;
345
0
  }
346
347
0
  const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);
348
    
349
0
  switch(image_type) {
350
0
    case FIT_BITMAP:
351
0
      if(FreeImage_GetBPP(src) == 32) {
352
        // convert to 24-bit
353
0
        return FreeImage_ConvertTo24Bits(src);
354
0
      }
355
0
      break;
356
0
    case FIT_RGBA16:
357
      // convert to RGB16
358
0
      return FreeImage_ConvertToRGB16(src);
359
0
    case FIT_RGBAF:
360
      // convert to RGBF
361
0
      return FreeImage_ConvertToRGBF(src);
362
0
    default:
363
      // unsupported image type
364
0
      return NULL;
365
0
  }
366
367
0
  return NULL;
368
0
}
369
370
371
// ==========================================================
372
373
FIBITMAP * DLL_CALLCONV
374
0
FreeImage_ColorQuantize(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize) {
375
0
  return FreeImage_ColorQuantizeEx(dib, quantize);
376
0
}
377
378
FIBITMAP * DLL_CALLCONV
379
0
FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize, int PaletteSize, int ReserveSize, RGBQUAD *ReservePalette) {
380
0
  if( PaletteSize < 2 ) PaletteSize = 2;
381
0
  if( PaletteSize > 256 ) PaletteSize = 256;
382
0
  if( ReserveSize < 0 ) ReserveSize = 0;
383
0
  if( ReserveSize > PaletteSize ) ReserveSize = PaletteSize;
384
0
  if (FreeImage_HasPixels(dib)) {
385
0
    const unsigned bpp = FreeImage_GetBPP(dib);
386
0
    if((FreeImage_GetImageType(dib) == FIT_BITMAP) && (bpp == 24 || bpp == 32)) {
387
0
      switch(quantize) {
388
0
        case FIQ_WUQUANT :
389
0
        {
390
0
          try {
391
0
            WuQuantizer Q (dib);
392
0
            FIBITMAP *dst = Q.Quantize(PaletteSize, ReserveSize, ReservePalette);
393
0
            if(dst) {
394
              // copy metadata from src to dst
395
0
              FreeImage_CloneMetadata(dst, dib);
396
0
            }
397
0
            return dst;
398
0
          } catch (const char *) {
399
0
            return NULL;
400
0
          }
401
0
          break;
402
0
        }
403
0
        case FIQ_NNQUANT :
404
0
        {
405
0
          if (bpp == 32) {
406
            // 32-bit images not supported by NNQUANT
407
0
            return NULL;
408
0
          }
409
          // sampling factor in range 1..30. 
410
          // 1 => slower (but better), 30 => faster. Default value is 1
411
0
          const int sampling = 1;
412
413
0
          NNQuantizer Q(PaletteSize);
414
0
          FIBITMAP *dst = Q.Quantize(dib, ReserveSize, ReservePalette, sampling);
415
0
          if(dst) {
416
            // copy metadata from src to dst
417
0
            FreeImage_CloneMetadata(dst, dib);
418
0
          }
419
0
          return dst;
420
0
        }
421
0
        case FIQ_LFPQUANT :
422
0
        {
423
0
          LFPQuantizer Q(PaletteSize);
424
0
          FIBITMAP *dst = Q.Quantize(dib, ReserveSize, ReservePalette);
425
0
          if(dst) {
426
            // copy metadata from src to dst
427
0
            FreeImage_CloneMetadata(dst, dib);
428
0
          }
429
0
          return dst;
430
0
        }
431
0
      }
432
0
    }
433
0
  }
434
435
0
  return NULL;
436
0
}
437
438
// ==========================================================
439
440
FIBITMAP * DLL_CALLCONV
441
0
FreeImage_ConvertFromRawBitsEx(BOOL copySource, BYTE *bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
442
0
  FIBITMAP *dib = NULL;
443
444
0
  if(copySource) {
445
    // allocate a FIBITMAP with internally managed pixel buffer
446
0
    dib = FreeImage_AllocateT(type, width, height, bpp, red_mask, green_mask, blue_mask);
447
0
    if(!dib) {
448
0
      return NULL;
449
0
    }
450
    // copy user provided pixel buffer into the dib
451
0
    const unsigned linesize = FreeImage_GetLine(dib);
452
0
    for(int y = 0; y < height; y++) {
453
0
      memcpy(FreeImage_GetScanLine(dib, y), bits, linesize);
454
      // next line in user's buffer
455
0
      bits += pitch;
456
0
    }
457
    // flip pixels vertically if needed
458
0
    if(topdown) {
459
0
      FreeImage_FlipVertical(dib);
460
0
    }
461
0
  }
462
0
  else {
463
    // allocate a FIBITMAP using a wrapper to user provided pixel buffer
464
0
    dib = FreeImage_AllocateHeaderForBits(bits, pitch, type, width, height, bpp, red_mask, green_mask, blue_mask);
465
0
    if(!dib) {
466
0
      return NULL;
467
0
    }
468
    // flip pixels vertically if needed
469
0
    if(topdown) {
470
0
      FreeImage_FlipVertical(dib);
471
0
    }
472
0
  }
473
474
0
  return dib;
475
0
}
476
477
FIBITMAP * DLL_CALLCONV
478
0
FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
479
0
  return FreeImage_ConvertFromRawBitsEx(TRUE /* copySource */, bits, FIT_BITMAP, width, height, pitch, bpp, red_mask, green_mask, blue_mask, topdown);
480
0
}
481
482
void DLL_CALLCONV
483
0
FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
484
0
  if (FreeImage_HasPixels(dib) && (bits != NULL)) {
485
0
    for (unsigned i = 0; i < FreeImage_GetHeight(dib); ++i) {
486
0
      BYTE *scanline = FreeImage_GetScanLine(dib, topdown ? (FreeImage_GetHeight(dib) - i - 1) : i);
487
488
0
      if ((bpp == 16) && (FreeImage_GetBPP(dib) == 16)) {
489
        // convert 555 to 565 or vice versa
490
491
0
        if ((red_mask == FI16_555_RED_MASK) && (green_mask == FI16_555_GREEN_MASK) && (blue_mask == FI16_555_BLUE_MASK)) {
492
0
          if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
493
0
            FreeImage_ConvertLine16_565_To16_555(bits, scanline, FreeImage_GetWidth(dib));
494
0
          } else {
495
0
            memcpy(bits, scanline, FreeImage_GetLine(dib));
496
0
          }
497
0
        } else {
498
0
          if ((FreeImage_GetRedMask(dib) == FI16_555_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_555_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_555_BLUE_MASK)) {
499
0
            FreeImage_ConvertLine16_555_To16_565(bits, scanline, FreeImage_GetWidth(dib));
500
0
          } else {
501
0
            memcpy(bits, scanline, FreeImage_GetLine(dib));
502
0
          }
503
0
        }
504
0
      } else if (FreeImage_GetBPP(dib) != bpp) {
505
0
                BOOL bIsTransparent = FreeImage_IsTransparent(dib);
506
0
        switch(FreeImage_GetBPP(dib)) {
507
0
          case 1 :
508
0
            switch(bpp) {
509
0
              CONVERT(1, 8)
510
0
              CONVERTTO16WITHPALETTE(1)
511
0
              CONVERTWITHPALETTE(1, 24)
512
0
                            CONVERTTO32WITHPALETTE(1)
513
0
                        }
514
515
0
            break;
516
517
0
          case 4 :
518
0
            switch(bpp) {
519
0
              CONVERT(4, 8)
520
0
              CONVERTTO16WITHPALETTE(4)
521
0
              CONVERTWITHPALETTE(4, 24)
522
0
                            CONVERTTO32WITHPALETTE(4)
523
0
            }
524
525
0
            break;
526
527
0
          case 8 :
528
0
            switch(bpp) {
529
0
              CONVERTTO16WITHPALETTE(8)
530
0
              CONVERTWITHPALETTE(8, 24)
531
0
                            CONVERTTO32WITHPALETTE(8)
532
0
            }
533
534
0
            break;
535
536
0
          case 24 :
537
0
            switch(bpp) {
538
0
              CONVERT(24, 8)
539
0
              CONVERTTO16(24)
540
0
              CONVERT(24, 32)
541
0
            }
542
543
0
            break;
544
545
0
          case 32 :
546
0
            switch(bpp) {
547
0
              CONVERT(32, 8)
548
0
              CONVERTTO16(32)
549
0
              CONVERT(32, 24)
550
0
            }
551
552
0
            break;
553
0
        }
554
0
      } else {
555
0
        memcpy(bits, scanline, FreeImage_GetLine(dib));
556
0
      }
557
558
0
      bits += pitch;
559
0
    }
560
0
  }
561
0
}