Coverage Report

Created: 2025-11-11 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/ConversionRGB16.cpp
Line
Count
Source
1
// ==========================================================
2
// Bitmap conversion routines
3
//
4
// Design and implementation by
5
// - Hervé Drolon (drolon@infonie.fr)
6
//
7
// This file is part of FreeImage 3
8
//
9
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
10
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
11
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
12
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
13
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
14
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
15
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
16
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
17
// THIS DISCLAIMER.
18
//
19
// Use at your own risk!
20
// ==========================================================
21
22
#include "FreeImage.h"
23
#include "Utilities.h"
24
25
// ----------------------------------------------------------
26
//   smart convert X to RGB16
27
// ----------------------------------------------------------
28
29
FIBITMAP * DLL_CALLCONV
30
0
FreeImage_ConvertToRGB16(FIBITMAP *dib) {
31
0
  FIBITMAP *src = NULL;
32
0
  FIBITMAP *dst = NULL;
33
34
0
  if(!FreeImage_HasPixels(dib)) return NULL;
35
36
0
  const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
37
38
  // check for allowed conversions 
39
0
  switch(src_type) {
40
0
    case FIT_BITMAP:
41
0
    {
42
      // convert to 24-bit if needed
43
0
      if((FreeImage_GetBPP(dib) == 24) || (FreeImage_GetBPP(dib) == 32)) {
44
0
        src = dib;
45
0
      } else {
46
0
        src = FreeImage_ConvertTo24Bits(dib);
47
0
        if(!src) return NULL;
48
0
      }
49
0
      break;
50
0
    }
51
0
    case FIT_UINT16:
52
      // allow conversion from unsigned 16-bit
53
0
      src = dib;
54
0
      break;
55
0
    case FIT_RGB16:
56
      // RGB16 type : clone the src
57
0
      return FreeImage_Clone(dib);
58
0
      break;
59
0
    case FIT_RGBA16:
60
      // allow conversion from 64-bit RGBA (ignore the alpha channel)
61
0
      src = dib;
62
0
      break;
63
0
    default:
64
0
      return NULL;
65
0
  }
66
67
  // allocate dst image
68
69
0
  const unsigned width = FreeImage_GetWidth(src);
70
0
  const unsigned height = FreeImage_GetHeight(src);
71
72
0
  dst = FreeImage_AllocateT(FIT_RGB16, width, height);
73
0
  if(!dst) {
74
0
    if(src != dib) {
75
0
      FreeImage_Unload(src);
76
0
    }
77
0
    return NULL;
78
0
  }
79
80
  // copy metadata from src to dst
81
0
  FreeImage_CloneMetadata(dst, src);
82
83
  // convert from src type to RGB16
84
85
0
  switch(src_type) {
86
0
    case FIT_BITMAP:
87
0
    {
88
      // Calculate the number of bytes per pixel (1 for 8-bit, 3 for 24-bit or 4 for 32-bit)
89
0
      const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
90
91
0
      for(unsigned y = 0; y < height; y++) {
92
0
        const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
93
0
        FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
94
0
        for(unsigned x = 0; x < width; x++) {
95
0
          dst_bits[x].red   = src_bits[FI_RGBA_RED] << 8;
96
0
          dst_bits[x].green = src_bits[FI_RGBA_GREEN] << 8;
97
0
          dst_bits[x].blue  = src_bits[FI_RGBA_BLUE] << 8;
98
0
          src_bits += bytespp;
99
0
        }
100
0
      }
101
0
    }
102
0
    break;
103
104
0
    case FIT_UINT16:
105
0
    {
106
0
      for(unsigned y = 0; y < height; y++) {
107
0
        const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y);
108
0
        FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
109
0
        for(unsigned x = 0; x < width; x++) {
110
          // convert by copying greyscale channel to each R, G, B channels
111
0
          dst_bits[x].red   = src_bits[x];
112
0
          dst_bits[x].green = src_bits[x];
113
0
          dst_bits[x].blue  = src_bits[x];
114
0
        }
115
0
      }
116
0
    }
117
0
    break;
118
119
0
    case FIT_RGBA16:
120
0
    {
121
0
      for(unsigned y = 0; y < height; y++) {
122
0
        const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
123
0
        FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
124
0
        for(unsigned x = 0; x < width; x++) {
125
          // convert and skip alpha channel
126
0
          dst_bits[x].red   = src_bits[x].red;
127
0
          dst_bits[x].green = src_bits[x].green;
128
0
          dst_bits[x].blue  = src_bits[x].blue;
129
0
        }
130
0
      }
131
0
    }
132
0
    break;
133
134
0
    default:
135
0
      break;
136
0
  }
137
138
0
  if(src != dib) {
139
0
    FreeImage_Unload(src);
140
0
  }
141
142
0
  return dst;
143
0
}
144