Coverage Report

Created: 2025-06-22 06:41

/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/Conversion16_555.cpp
Line
Count
Source (jump to first uncovered line)
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
//
9
// This file is part of FreeImage 3
10
//
11
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
12
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
13
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
14
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
15
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
16
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
17
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
18
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
19
// THIS DISCLAIMER.
20
//
21
// Use at your own risk!
22
// ==========================================================
23
24
#include "FreeImage.h"
25
#include "Utilities.h"
26
27
// ----------------------------------------------------------
28
29
0
#define RGB555(b, g, r) ((((b) >> 3) << FI16_555_BLUE_SHIFT) | (((g) >> 3) << FI16_555_GREEN_SHIFT) | (((r) >> 3) << FI16_555_RED_SHIFT))
30
31
// ----------------------------------------------------------
32
//  internal conversions X to 16 bits (555)
33
// ----------------------------------------------------------
34
35
void DLL_CALLCONV
36
0
FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
37
0
  WORD *new_bits = (WORD *)target;
38
39
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
40
0
    int index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
41
42
0
    new_bits[cols] = RGB555(palette[index].rgbBlue, palette[index].rgbGreen, palette[index].rgbRed);
43
0
  }
44
0
}
45
46
void DLL_CALLCONV
47
0
FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
48
0
  WORD *new_bits = (WORD *)target;
49
0
  BOOL lonibble = FALSE;
50
0
  int x = 0;
51
52
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
53
0
    RGBQUAD *grab_palette;
54
55
0
    if (lonibble) {
56
0
      grab_palette = palette + LOWNIBBLE(source[x++]);
57
0
    } else {
58
0
      grab_palette = palette + (HINIBBLE(source[x]) >> 4);                
59
0
    }
60
61
0
    new_bits[cols] = RGB555(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
62
63
0
    lonibble = !lonibble;
64
0
  }
65
0
}
66
67
void DLL_CALLCONV
68
0
FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
69
0
  WORD *new_bits = (WORD *)target;
70
71
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
72
0
    RGBQUAD *grab_palette = palette + source[cols];
73
74
0
    new_bits[cols] = RGB555(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
75
0
  }
76
0
}
77
78
void DLL_CALLCONV
79
0
FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels) {
80
0
  WORD *src_bits = (WORD *)source;
81
0
  WORD *new_bits = (WORD *)target;
82
83
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
84
0
    new_bits[cols] = RGB555((((src_bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F,
85
0
                          (((src_bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
86
0
                (((src_bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
87
0
  }
88
0
}
89
90
void DLL_CALLCONV
91
0
FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels) {
92
0
  WORD *new_bits = (WORD *)target;
93
94
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
95
0
    new_bits[cols] = RGB555(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
96
97
0
    source += 3;
98
0
  }
99
0
}
100
101
void DLL_CALLCONV
102
0
FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels) {
103
0
  WORD *new_bits = (WORD *)target;
104
105
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
106
0
    new_bits[cols] = RGB555(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
107
108
0
    source += 4;
109
0
  }
110
0
}
111
112
// ----------------------------------------------------------
113
//   smart convert X to 16 bits
114
// ----------------------------------------------------------
115
116
FIBITMAP * DLL_CALLCONV
117
0
FreeImage_ConvertTo16Bits555(FIBITMAP *dib) {
118
0
  if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) return NULL;
119
120
0
  const int width = FreeImage_GetWidth(dib);
121
0
  const int height = FreeImage_GetHeight(dib);
122
0
  const int bpp = FreeImage_GetBPP(dib);
123
124
0
  if(bpp == 16) {
125
0
    if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
126
      // RGB 565
127
0
      FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
128
0
      if(new_dib == NULL) {
129
0
        return NULL;
130
0
      }
131
0
      for (int rows = 0; rows < height; rows++) {
132
0
        FreeImage_ConvertLine16_565_To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
133
0
      }
134
135
      // copy metadata from src to dst
136
0
      FreeImage_CloneMetadata(new_dib, dib);
137
138
0
      return new_dib;
139
0
    } else {
140
      // RGB 555
141
0
      return FreeImage_Clone(dib);
142
0
    }
143
0
  }
144
0
  else {
145
    // other bpp cases => convert to RGB 555
146
0
    FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
147
0
    if(new_dib == NULL) {
148
0
      return NULL;
149
0
    }
150
151
    // copy metadata from src to dst
152
0
    FreeImage_CloneMetadata(new_dib, dib);
153
154
0
    switch (bpp) {
155
0
      case 1 :
156
0
      {
157
0
        for (int rows = 0; rows < height; rows++) {
158
0
          FreeImage_ConvertLine1To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
159
0
        }
160
161
0
        return new_dib;
162
0
      }
163
164
0
      case 4 :
165
0
      {
166
0
        for (int rows = 0; rows < height; rows++) {
167
0
          FreeImage_ConvertLine4To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
168
0
        }
169
170
0
        return new_dib;
171
0
      }
172
173
0
      case 8 :
174
0
      {
175
0
        for (int rows = 0; rows < height; rows++) {
176
0
          FreeImage_ConvertLine8To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
177
0
        }
178
179
0
        return new_dib;
180
0
      }
181
182
0
      case 24 :
183
0
      {
184
0
        for (int rows = 0; rows < height; rows++) {
185
0
          FreeImage_ConvertLine24To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
186
0
        }
187
188
0
        return new_dib;
189
0
      }
190
191
0
      case 32 :
192
0
      {
193
0
        for (int rows = 0; rows < height; rows++) {
194
0
          FreeImage_ConvertLine32To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
195
0
        }
196
197
0
        return new_dib;
198
0
      }
199
200
0
      default :
201
        // unreachable code ...
202
0
        FreeImage_Unload(new_dib);
203
0
        break;
204
205
0
    }
206
0
  }
207
208
0
  return NULL;
209
0
}