libdmtx 0.7.8.7
libdmtx is a software library that enables programs to read and write Data Matrix barcodes of the modern ECC200 variety.
Loading...
Searching...
No Matches
dmtximage.c
Go to the documentation of this file.
1
17#include <assert.h>
18#include <stdlib.h>
19
20#include "dmtx.h"
21#include "dmtxstatic.h"
22
78extern DmtxImage *dmtxImageCreate(unsigned char *pxl, int width, int height, int pack)
79{
80 // DmtxPassFail err;
81 DmtxImage *img = NULL;
82
83 if (pxl == NULL || width < 1 || height < 1) {
84 return NULL;
85 }
86
87 img = (DmtxImage *)calloc(1, sizeof(DmtxImage));
88 if (img == NULL) {
89 return NULL;
90 }
91
92 img->pxl = pxl;
93 img->width = width;
94 img->height = height;
95 img->pixelPacking = pack;
96 img->bitsPerPixel = getBitsPerPixel(pack);
97 img->bytesPerPixel = img->bitsPerPixel / 8;
98 img->rowPadBytes = 0;
99 img->rowSizeBytes = img->width * img->bytesPerPixel + img->rowPadBytes;
100 img->imageFlip = DmtxFlipNone;
101
102 /* Leave channelStart[] and bitsPerChannel[] with zeros from calloc */
103 img->channelCount = 0;
104
105 switch (pack) {
106 case DmtxPackCustom:
107 break;
108 case DmtxPack1bppK:
109 dmtxImageSetChannel(img, 0, 1);
110 return NULL; /* unsupported packing order */
111 /* break; */
112 case DmtxPack8bppK:
113 dmtxImageSetChannel(img, 0, 8);
114 break;
115 case DmtxPack16bppRGB:
116 case DmtxPack16bppBGR:
118 dmtxImageSetChannel(img, 0, 5);
119 dmtxImageSetChannel(img, 5, 5);
120 dmtxImageSetChannel(img, 10, 5);
121 break;
122 case DmtxPack24bppRGB:
123 case DmtxPack24bppBGR:
127 dmtxImageSetChannel(img, 0, 8);
128 dmtxImageSetChannel(img, 8, 8);
129 dmtxImageSetChannel(img, 16, 8);
130 break;
133 dmtxImageSetChannel(img, 0, 5);
134 dmtxImageSetChannel(img, 5, 5);
135 dmtxImageSetChannel(img, 10, 5);
136 break;
139 dmtxImageSetChannel(img, 1, 5);
140 dmtxImageSetChannel(img, 6, 5);
141 dmtxImageSetChannel(img, 11, 5);
142 break;
145 dmtxImageSetChannel(img, 8, 8);
146 dmtxImageSetChannel(img, 16, 8);
147 dmtxImageSetChannel(img, 24, 8);
148 break;
150 dmtxImageSetChannel(img, 0, 8);
151 dmtxImageSetChannel(img, 8, 8);
152 dmtxImageSetChannel(img, 16, 8);
153 dmtxImageSetChannel(img, 24, 8);
154 break;
155 default:
156 return NULL;
157 }
158
159 return img;
160}
161
168{
169 if (img == NULL || *img == NULL) {
170 return DmtxFail;
171 }
172
173 free(*img);
174
175 *img = NULL;
176
177 return DmtxPass;
178}
179
183extern DmtxPassFail dmtxImageSetChannel(DmtxImage *img, int channelStart, int bitsPerChannel)
184{
185 if (img->channelCount >= 4) { /* IMAGE_MAX_CHANNEL */
186 return DmtxFail;
187 }
188
189 /* New channel extends beyond pixel data */
190 /* if(channelStart + bitsPerChannel > img->bitsPerPixel)
191 return DmtxFail; */
192
193 img->bitsPerChannel[img->channelCount] = bitsPerChannel;
194 img->channelStart[img->channelCount] = channelStart;
195 (img->channelCount)++;
196
197 return DmtxPass;
198}
199
203extern DmtxPassFail dmtxImageSetProp(DmtxImage *img, int prop, int value)
204{
205 if (img == NULL) {
206 return DmtxFail;
207 }
208
209 switch (prop) {
211 img->rowPadBytes = value;
212 img->rowSizeBytes = img->width * (img->bitsPerPixel / 8) + img->rowPadBytes;
213 break;
215 img->imageFlip = value;
216 break;
217 default:
218 break;
219 }
220
221 return DmtxPass;
222}
223
228extern int dmtxImageGetProp(DmtxImage *img, int prop)
229{
230 if (img == NULL) {
231 return DmtxUndefined;
232 }
233
234 switch (prop) {
235 case DmtxPropWidth:
236 return img->width;
237 case DmtxPropHeight:
238 return img->height;
240 return img->pixelPacking;
242 return img->bitsPerPixel;
244 return img->bytesPerPixel;
246 return img->rowPadBytes;
248 return img->rowSizeBytes;
250 return img->imageFlip;
252 return img->channelCount;
253 default:
254 break;
255 }
256
257 return DmtxUndefined;
258}
259
263extern int dmtxImageGetByteOffset(DmtxImage *img, int x, int y)
264{
265 DmtxAssert(img != NULL);
266 DmtxAssert(!(img->imageFlip & DmtxFlipX)); /* DmtxFlipX is not an option */
267
268 if (dmtxImageContainsInt(img, 0, x, y) == DmtxFalse) {
269 return DmtxUndefined;
270 }
271
272 if (img->imageFlip & DmtxFlipY) {
273 return (y * img->rowSizeBytes + x * img->bytesPerPixel);
274 }
275
276 return ((img->height - y - 1) * img->rowSizeBytes + x * img->bytesPerPixel);
277}
278
293extern DmtxPassFail dmtxImageGetPixelValue(DmtxImage *img, int x, int y, int channel, int *value)
294{
295 int offset;
296 /* unsigned char *pixelPtr;
297 int pixelValue;
298 int mask;
299 int bitShift; */
300
301 DmtxAssert(img != NULL);
302 DmtxAssert(channel < img->channelCount);
303
304 offset = dmtxImageGetByteOffset(img, x, y);
305 if (offset == DmtxUndefined) {
306 return DmtxFail;
307 }
308
309 switch (img->bitsPerChannel[channel]) {
310 case 1:
311 /* DmtxAssert(img->bitsPerPixel == 1);
312 mask = 0x01 << (7 - offset%8);
313 *value = (img->pxl[offset/8] & mask) ? 255 : 0; */
314 break;
315 case 5:
316 /* XXX might be expensive if we want to scale perfect 0-255 range */
317 /* DmtxAssert(img->bitsPerPixel == 16);
318 pixelPtr = img->pxl + (offset * (img->bitsPerPixel/8));
319 pixelValue = (*pixelPtr << 8) | (*(pixelPtr+1));
320 bitShift = img->bitsPerPixel - 5 - img->channelStart[channel];
321 mask = 0x1f << bitShift;
322 *value = (((pixelValue & mask) >> bitShift) << 3); */
323 break;
324 case 8:
325 DmtxAssert(img->channelStart[channel] % 8 == 0);
326 DmtxAssert(img->bitsPerPixel % 8 == 0);
327 *value = img->pxl[offset + channel];
328 break;
329 }
330
331 return DmtxPass;
332}
333
337extern DmtxPassFail dmtxImageSetPixelValue(DmtxImage *img, int x, int y, int channel, int value)
338{
339 int offset;
340 /* unsigned char *pixelPtr; */
341 /* int pixelValue; */
342 /* int mask; */
343 /* int bitShift; */
344
345 DmtxAssert(img != NULL);
346 DmtxAssert(channel < img->channelCount);
347
348 offset = dmtxImageGetByteOffset(img, x, y);
349 if (offset == DmtxUndefined) {
350 return DmtxFail;
351 }
352
353 switch (img->bitsPerChannel[channel]) {
354 case 1:
355 /* DmtxAssert(img->bitsPerPixel == 1);
356 mask = 0x01 << (7 - offset%8);
357 *value = (img->pxl[offset/8] & mask) ? 255 : 0; */
358 break;
359 case 5:
360 /* XXX might be expensive if we want to scale perfect 0-255 range */
361 /* DmtxAssert(img->bitsPerPixel == 16);
362 pixelPtr = img->pxl + (offset * (img->bitsPerPixel/8));
363 pixelValue = (*pixelPtr << 8) | (*(pixelPtr+1));
364 bitShift = img->bitsPerPixel - 5 - img->channelStart[channel];
365 mask = 0x1f << bitShift;
366 *value = (((pixelValue & mask) >> bitShift) << 3); */
367 break;
368 case 8:
369 DmtxAssert(img->channelStart[channel] % 8 == 0);
370 DmtxAssert(img->bitsPerPixel % 8 == 0);
371 img->pxl[offset + channel] = value;
372 break;
373 }
374
375 return DmtxPass;
376}
377
386extern DmtxBoolean dmtxImageContainsInt(DmtxImage *img, int margin, int x, int y)
387{
388 DmtxAssert(img != NULL);
389
390 if (x - margin >= 0 && x + margin < img->width && y - margin >= 0 && y + margin < img->height) {
391 return DmtxTrue;
392 }
393
394 return DmtxFalse;
395}
396
404extern DmtxBoolean dmtxImageContainsFloat(DmtxImage *img, double x, double y)
405{
406 DmtxAssert(img != NULL);
407
408 if (x >= 0.0 && x < (double)img->width && y >= 0.0 && y < (double)img->height) {
409 return DmtxTrue;
410 }
411
412 return DmtxFalse;
413}
414
418static int getBitsPerPixel(int pack)
419{
420 switch (pack) {
421 case DmtxPack1bppK:
422 return 1;
423 case DmtxPack8bppK:
424 return 8;
425 case DmtxPack16bppRGB:
428 case DmtxPack16bppBGR:
432 return 16;
433 case DmtxPack24bppRGB:
434 case DmtxPack24bppBGR:
436 return 24;
442 return 32;
443 default:
444 break;
445 }
446
447 return DmtxUndefined;
448}
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
#define DmtxPassFail
Definition dmtx.h:42
@ DmtxPropBytesPerPixel
每像素所需要的byte数
Definition dmtx.h:200
@ DmtxPropRowSizeBytes
每一行(包括填充)在内存中的总字节数
Definition dmtx.h:202
@ DmtxPropImageFlip
图像是否需要翻转,通常用于处理上下颠倒的图像 DmtxFlip
Definition dmtx.h:203
@ DmtxPropPixelPacking
图像格式类型,像素打包方式 DmtxPackOrder
Definition dmtx.h:198
@ DmtxPropWidth
图像宽度
Definition dmtx.h:196
@ DmtxPropRowPadBytes
每行像素在内存中的填充或对齐字节数
Definition dmtx.h:201
@ DmtxPropChannelCount
图像通道数
Definition dmtx.h:204
@ DmtxPropBitsPerPixel
每像素所需要的bit数
Definition dmtx.h:199
@ DmtxPropHeight
图像高度
Definition dmtx.h:197
#define DmtxTrue
Definition dmtx.h:47
@ DmtxPack32bppBGRX
Definition dmtx.h:237
@ DmtxPack24bppRGB
Definition dmtx.h:231
@ DmtxPack24bppYCbCr
Definition dmtx.h:233
@ DmtxPack16bppXRGB
Definition dmtx.h:225
@ DmtxPack16bppRGB
Definition dmtx.h:223
@ DmtxPack16bppXBGR
Definition dmtx.h:228
@ DmtxPack32bppCMYK
Definition dmtx.h:239
@ DmtxPackCustom
Definition dmtx.h:217
@ DmtxPack24bppBGR
Definition dmtx.h:232
@ DmtxPack16bppBGRX
Definition dmtx.h:227
@ DmtxPack8bppK
Definition dmtx.h:221
@ DmtxPack32bppRGBX
Definition dmtx.h:235
@ DmtxPack16bppRGBX
Definition dmtx.h:224
@ DmtxPack16bppYCbCr
Definition dmtx.h:229
@ DmtxPack1bppK
Definition dmtx.h:219
@ DmtxPack32bppXRGB
Definition dmtx.h:236
@ DmtxPack32bppXBGR
Definition dmtx.h:238
@ DmtxPack16bppBGR
Definition dmtx.h:226
#define DmtxBoolean
Definition dmtx.h:46
@ DmtxFlipY
Definition dmtx.h:246
@ DmtxFlipX
Definition dmtx.h:245
@ DmtxFlipNone
Definition dmtx.h:244
#define DmtxPass
Definition dmtx.h:43
#define DmtxUndefined
Definition dmtx.h:40
#define DmtxFalse
Definition dmtx.h:48
#define DmtxFail
Definition dmtx.h:44
static int getBitsPerPixel(int pack)
根据给定的打包方式(pack)返回每个像素所占的位数
Definition dmtximage.c:418
DmtxPassFail dmtxImageSetProp(DmtxImage *img, int prop, int value)
设置图像属性
Definition dmtximage.c:203
DmtxPassFail dmtxImageSetChannel(DmtxImage *img, int channelStart, int bitsPerChannel)
设置图像的颜色通道信息,包括每个通道的起始位和位数。
Definition dmtximage.c:183
DmtxPassFail dmtxImageDestroy(DmtxImage **img)
Free libdmtx image memory.
Definition dmtximage.c:167
DmtxBoolean dmtxImageContainsInt(DmtxImage *img, int margin, int x, int y)
判断坐标 (x, y) 是否在图像范围内
Definition dmtximage.c:386
DmtxImage * dmtxImageCreate(unsigned char *pxl, int width, int height, int pack)
libdmtx stores image data as a large one-dimensional array of packed pixels, reading from the array w...
Definition dmtximage.c:78
int dmtxImageGetByteOffset(DmtxImage *img, int x, int y)
根据给定的坐标 (x, y) 计算并返回图像中对应像素的字节偏移量
Definition dmtximage.c:263
int dmtxImageGetProp(DmtxImage *img, int prop)
获取图像属性
Definition dmtximage.c:228
DmtxPassFail dmtxImageSetPixelValue(DmtxImage *img, int x, int y, int channel, int value)
设置指定坐标、通道的像素值
Definition dmtximage.c:337
DmtxBoolean dmtxImageContainsFloat(DmtxImage *img, double x, double y)
判断坐标 (x, y) 是否在图像范围内
Definition dmtximage.c:404
DmtxPassFail dmtxImageGetPixelValue(DmtxImage *img, int x, int y, int channel, int *value)
获取指定坐标的像素值
Definition dmtximage.c:293
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
#define DmtxAssert(expr)
Definition dmtxstatic.h:96
int imageFlip
图像是否需要翻转,通常用于处理上下颠倒的图像 DmtxFlip
Definition dmtx.h:331
int pixelPacking
图像格式类型,像素打包方式 DmtxPackOrder
Definition dmtx.h:326
int height
图像的高度,以像素为单位
Definition dmtx.h:325
int width
图像的宽度,以像素为单位
Definition dmtx.h:324
int channelStart[4]
每个通道在像素数据中的起始位置(位偏移)
Definition dmtx.h:333
unsigned char * pxl
实际的像素数据缓冲区
Definition dmtx.h:335
int bytesPerPixel
每个像素的字节数
Definition dmtx.h:328
int rowPadBytes
每行像素在内存中的填充或对齐字节数
Definition dmtx.h:329
int bitsPerChannel[4]
每个通道的位数,描述每个颜色分量的精度
Definition dmtx.h:334
int channelCount
图像的通道数量,如RGB图像为3,CMYK图像为4
Definition dmtx.h:332
int rowSizeBytes
每一行(包括填充)在内存中的总字节数
Definition dmtx.h:330
int bitsPerPixel
每个像素的位数
Definition dmtx.h:327