Coverage Report

Created: 2025-06-22 06:41

/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/PluginCUT.cpp
Line
Count
Source (jump to first uncovered line)
1
// ==========================================================
2
// CUT Loader
3
//
4
// Design and implementation by
5
// - Floris van den Berg (flvdberg@wxs.nl)
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
//   Constants + headers
27
// ----------------------------------------------------------
28
29
#ifdef _WIN32
30
#pragma pack(push, 1)
31
#else
32
#pragma pack(1)
33
#endif
34
35
typedef struct tagCUTHEADER {
36
  WORD width;
37
  WORD height;
38
  LONG dummy;
39
} CUTHEADER;
40
41
#ifdef _WIN32
42
#pragma pack(pop)
43
#else
44
#pragma pack()
45
#endif
46
47
// ==========================================================
48
// Plugin Interface
49
// ==========================================================
50
51
static int s_format_id;
52
53
// ==========================================================
54
// Plugin Implementation
55
// ==========================================================
56
57
static const char * DLL_CALLCONV
58
2
Format() {
59
2
  return "CUT";
60
2
}
61
62
static const char * DLL_CALLCONV
63
0
Description() {
64
0
  return "Dr. Halo";
65
0
}
66
67
static const char * DLL_CALLCONV
68
0
Extension() {
69
0
  return "cut";
70
0
}
71
72
static const char * DLL_CALLCONV
73
0
RegExpr() {
74
0
  return NULL;
75
0
}
76
77
static const char * DLL_CALLCONV
78
0
MimeType() {
79
0
  return "image/x-cut";
80
0
}
81
82
static BOOL DLL_CALLCONV
83
23.9k
Validate(FreeImageIO *io, fi_handle handle) {
84
23.9k
  return FALSE;
85
23.9k
}
86
87
static BOOL DLL_CALLCONV
88
0
SupportsExportDepth(int depth) {
89
0
  return FALSE;
90
0
}
91
92
static BOOL DLL_CALLCONV 
93
0
SupportsExportType(FREE_IMAGE_TYPE type) {
94
0
  return FALSE;
95
0
}
96
97
static BOOL DLL_CALLCONV
98
0
SupportsNoPixels() {
99
0
  return TRUE;
100
0
}
101
102
// ----------------------------------------------------------
103
104
static FIBITMAP * DLL_CALLCONV
105
0
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
106
0
  FIBITMAP *dib = NULL;
107
108
0
  if(!handle) {
109
0
    return NULL;
110
0
  }
111
112
0
  try {
113
0
    CUTHEADER header;   
114
115
0
    BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
116
117
    // read the cut header
118
119
0
    if(io->read_proc(&header, 1, sizeof(CUTHEADER), handle) != sizeof(CUTHEADER)) {
120
0
      throw FI_MSG_ERROR_PARSING;
121
0
    }
122
123
#ifdef FREEIMAGE_BIGENDIAN
124
    SwapShort((WORD *)&header.width);
125
    SwapShort((WORD *)&header.height);
126
#endif
127
128
0
    if ((header.width == 0) || (header.height == 0)) {
129
0
      return NULL;
130
0
    }
131
132
    // allocate a new bitmap
133
134
0
    dib = FreeImage_AllocateHeader(header_only, header.width, header.height, 8);
135
136
0
    if (dib == NULL) {
137
0
      throw FI_MSG_ERROR_DIB_MEMORY;
138
0
    }
139
140
    // stuff it with a palette
141
142
0
    RGBQUAD *palette = FreeImage_GetPalette(dib);
143
144
0
    for (int j = 0; j < 256; ++j) {
145
0
      palette[j].rgbBlue = palette[j].rgbGreen = palette[j].rgbRed = (BYTE)j;
146
0
    }
147
    
148
0
    if(header_only) {
149
      // header only mode
150
0
      return dib;
151
0
    }
152
153
    // unpack the RLE bitmap bits
154
155
0
    BYTE *bits = FreeImage_GetScanLine(dib, header.height - 1);
156
157
0
    unsigned i = 0, k = 0;
158
0
    unsigned pitch = FreeImage_GetPitch(dib);
159
0
    unsigned size = header.width * header.height;
160
0
    BYTE count = 0, run = 0;
161
162
0
    while (i < size) {
163
0
      if(io->read_proc(&count, 1, sizeof(BYTE), handle) != 1) {
164
0
        throw FI_MSG_ERROR_PARSING;
165
0
      }
166
167
0
      if (count == 0) {
168
0
        k = 0;
169
0
        bits -= pitch;
170
171
        // paint shop pro adds two useless bytes here...
172
173
0
        io->read_proc(&count, 1, sizeof(BYTE), handle);
174
0
        io->read_proc(&count, 1, sizeof(BYTE), handle);
175
176
0
        continue;
177
0
      }
178
179
0
      if (count & 0x80) {
180
0
        count &= ~(0x80);
181
182
0
        if(io->read_proc(&run, 1, sizeof(BYTE), handle) != 1) {
183
0
          throw FI_MSG_ERROR_PARSING;
184
0
        }
185
186
0
        if(k + count <= header.width) {
187
0
          memset(bits + k, run, count);
188
0
        } else {
189
0
          throw FI_MSG_ERROR_PARSING;
190
0
        }
191
0
      } else {
192
0
        if(k + count <= header.width) {
193
0
          if(io->read_proc(&bits[k], count, sizeof(BYTE), handle) != 1) {
194
0
            throw FI_MSG_ERROR_PARSING;
195
0
          }
196
0
        } else {
197
0
          throw FI_MSG_ERROR_PARSING;
198
0
        }
199
0
      }
200
201
0
      k += count;
202
0
      i += count;
203
0
    }
204
205
0
    return dib;
206
207
0
  } catch(const char* text) {
208
0
    if(dib) {
209
0
      FreeImage_Unload(dib);
210
0
    }
211
0
    FreeImage_OutputMessageProc(s_format_id, text);
212
0
    return NULL;
213
0
  }
214
0
}
215
216
// ==========================================================
217
//   Init
218
// ==========================================================
219
220
void DLL_CALLCONV
221
2
InitCUT(Plugin *plugin, int format_id) {
222
2
  s_format_id = format_id;
223
224
2
  plugin->format_proc = Format;
225
2
  plugin->description_proc = Description;
226
2
  plugin->extension_proc = Extension;
227
2
  plugin->regexpr_proc = RegExpr;
228
2
  plugin->open_proc = NULL;
229
2
  plugin->close_proc = NULL;
230
2
  plugin->pagecount_proc = NULL;
231
2
  plugin->pagecapability_proc = NULL;
232
2
  plugin->load_proc = Load;
233
2
  plugin->save_proc = NULL;
234
2
  plugin->validate_proc = Validate;
235
2
  plugin->mime_proc = MimeType;
236
2
  plugin->supports_export_bpp_proc = SupportsExportDepth;
237
2
  plugin->supports_export_type_proc = SupportsExportType;
238
2
  plugin->supports_icc_profiles_proc = NULL;
239
2
  plugin->supports_no_pixels_proc = SupportsNoPixels;
240
2
}