Coverage Report

Created: 2025-11-24 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/Conversion16_565.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
//
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
//  internal conversions X to 16 bits (565)
29
// ----------------------------------------------------------
30
31
void DLL_CALLCONV
32
0
FreeImage_ConvertLine1To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
33
0
  WORD *new_bits = (WORD *)target;
34
35
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
36
0
    int index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
37
38
0
    new_bits[cols] = RGB565(palette[index].rgbBlue, palette[index].rgbGreen, palette[index].rgbRed);
39
0
  }
40
0
}
41
42
void DLL_CALLCONV
43
0
FreeImage_ConvertLine4To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
44
0
  WORD *new_bits = (WORD *)target;
45
0
  BOOL lonibble = FALSE;
46
0
  int x = 0;
47
48
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
49
0
    RGBQUAD *grab_palette;
50
51
0
    if (lonibble) {
52
0
      grab_palette = palette + LOWNIBBLE(source[x++]);
53
0
    } else {
54
0
      grab_palette = palette + (HINIBBLE(source[x]) >> 4);                
55
0
    }
56
57
0
    new_bits[cols] = RGB565(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
58
59
0
    lonibble = !lonibble;
60
0
  }
61
0
}
62
63
void DLL_CALLCONV
64
0
FreeImage_ConvertLine8To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
65
0
  WORD *new_bits = (WORD *)target;
66
67
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
68
0
    RGBQUAD *grab_palette = palette + source[cols];
69
70
0
    new_bits[cols] = RGB565(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
71
0
  }
72
0
}
73
74
void DLL_CALLCONV
75
0
FreeImage_ConvertLine16_555_To16_565(BYTE *target, BYTE *source, int width_in_pixels) {
76
0
  WORD *src_bits = (WORD *)source;
77
0
  WORD *new_bits = (WORD *)target;
78
79
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
80
0
    new_bits[cols] = RGB565((((src_bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F,
81
0
                          (((src_bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
82
0
                (((src_bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
83
0
  }
84
0
}
85
86
void DLL_CALLCONV
87
0
FreeImage_ConvertLine24To16_565(BYTE *target, BYTE *source, int width_in_pixels) {
88
0
  WORD *new_bits = (WORD *)target;
89
90
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
91
0
    new_bits[cols] = RGB565(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
92
93
0
    source += 3;
94
0
  }
95
0
}
96
97
void DLL_CALLCONV
98
0
FreeImage_ConvertLine32To16_565(BYTE *target, BYTE *source, int width_in_pixels) {
99
0
  WORD *new_bits = (WORD *)target;
100
101
0
  for (int cols = 0; cols < width_in_pixels; cols++) {
102
0
    new_bits[cols] = RGB565(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
103
104
0
    source += 4;
105
0
  }
106
0
}
107
108
// ----------------------------------------------------------
109
//   smart convert X to 16 bits (565)
110
// ----------------------------------------------------------
111
112
FIBITMAP * DLL_CALLCONV
113
0
FreeImage_ConvertTo16Bits565(FIBITMAP *dib) {
114
0
  if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) return NULL;
115
116
0
  const int width = FreeImage_GetWidth(dib);
117
0
  const int height = FreeImage_GetHeight(dib);
118
0
  const int bpp = FreeImage_GetBPP(dib);
119
120
0
  if(bpp == 16) {
121
0
    if ((FreeImage_GetRedMask(dib) == FI16_555_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_555_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_555_BLUE_MASK)) {
122
      // RGB 555
123
0
      FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK);
124
0
      if(new_dib == NULL) {
125
0
        return NULL;
126
0
      }
127
0
      for (int rows = 0; rows < height; rows++) {
128
0
        FreeImage_ConvertLine16_555_To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
129
0
      }
130
131
      // copy metadata from src to dst
132
0
      FreeImage_CloneMetadata(new_dib, dib);
133
134
0
      return new_dib;
135
0
    } else {
136
      // RGB 565
137
0
      return FreeImage_Clone(dib);
138
0
    }
139
0
  }
140
0
  else {
141
    // other bpp cases => convert to RGB 565
142
0
    FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK);
143
0
    if(new_dib == NULL) {
144
0
      return NULL;
145
0
    }
146
147
    // copy metadata from src to dst
148
0
    FreeImage_CloneMetadata(new_dib, dib);
149
150
0
    switch (bpp) {
151
0
      case 1 :
152
0
      {
153
0
        for (int rows = 0; rows < height; rows++) {
154
0
          FreeImage_ConvertLine1To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
155
0
        }
156
157
0
        return new_dib;
158
0
      }
159
160
0
      case 4 :
161
0
      {
162
0
        for (int rows = 0; rows < height; rows++) {
163
0
          FreeImage_ConvertLine4To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
164
0
        }
165
166
0
        return new_dib;
167
0
      }
168
169
0
      case 8 :
170
0
      {
171
0
        for (int rows = 0; rows < height; rows++) {
172
0
          FreeImage_ConvertLine8To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
173
0
        }
174
175
0
        return new_dib;
176
0
      }
177
178
0
      case 24 :
179
0
      {
180
0
        for (int rows = 0; rows < height; rows++) {
181
0
          FreeImage_ConvertLine24To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
182
0
        }
183
184
0
        return new_dib;
185
0
      }
186
187
0
      case 32 :
188
0
      {
189
0
        for (int rows = 0; rows < height; rows++) {
190
0
          FreeImage_ConvertLine32To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
191
0
        }
192
193
0
        return new_dib;
194
0
      }
195
196
0
      default :
197
        // unreachable code ...
198
0
        FreeImage_Unload(new_dib);
199
0
        break;
200
0
    }
201
0
  }
202
203
0
  return NULL;
204
0
}