Простая программа, отображает пиксели в виде RGB-кубика.
/* Отображение цветового пространства в виде RGB-куба */
#include <stdio.h> /* printf() */
#include <FreeImage.h>
#include <stdlib.h>
int main (int argc, char **argv) {
char *filename_i;
char *filename_o;
if (argc < 3) {
printf("%s [filename_i] [filename_o]\n", argv[0]);
return -1;
}
filename_i = argv[1];
filename_o = argv[2];
FreeImage_Initialise (1);
FIBITMAP *dib0, *dib1;
dib0 = FreeImage_Load(FreeImage_GetFIFFromFilename(filename_i), filename_i, 0);
BYTE *data0 = FreeImage_GetBits(dib0);
WORD w0 = FreeImage_GetWidth(dib0);
WORD h0 = FreeImage_GetHeight(dib0);
WORD bpp0 = FreeImage_GetBPP(dib0);
bpp0 /= 8;
WORD stride0 = FreeImage_GetLine(dib0);
printf("w: %d\n", w0);
printf("h: %d\n", h0);
printf("bpp: %d\n", bpp0);
printf("stride: %d\n", stride0);
const int W = 256;
const int H = 256;
WORD w1 = 3*W;
WORD h1 = H;
WORD bpp1 = 3;
dib1 = FreeImage_Allocate(w1,h1,bpp1*8); // bytes per pixel
printf("%d %d %d\n",
FreeImage_GetWidth(dib1),
FreeImage_GetHeight(dib1),
FreeImage_GetBPP(dib1));
WORD stride1 = FreeImage_GetLine(dib1);
BYTE *data1 = FreeImage_GetBits(dib1);
#define min(a,b) ((a <= b)?(a):(b))
#define max(a,b) ((a > b)?(a):(b))
#define normX(d,x) max(0,min((w##d)-1,(x)))
#define normY(d,y) max(0,min((h##d)-1,(y)))
#define fB(d,x,y) data##d[(y)*stride##d+(x)*bpp##d+0]
#define fG(d,x,y) data##d[(y)*stride##d+(x)*bpp##d+1]
#define fR(d,x,y) data##d[(y)*stride##d+(x)*bpp##d+2]
// safe pixel access
#define sB(d,x,y) data##d[normY(d,(y))*stride##d+normX(d,(x))*bpp##d+0]
#define sG(d,x,y) data##d[normY(d,(y))*stride##d+normX(d,(x))*bpp##d+1]
#define sR(d,x,y) data##d[normY(d,(y))*stride##d+normX(d,(x))*bpp##d+2]
// Фильтр по голограммам.
for (int y = 0; y < h0; y++) {
for (int x = 0; x < w0; x++) {
int r00 = fR(0,x,y);
int g00 = fG(0,x,y);
int b00 = fB(0,x,y);
if ((b00 > 120) && (r00+g00 < 10)) {
printf("%d %d : %02X %02X %02X\n", x, y, r00, g00, b00);
}
int X1,Y1;
int X2,Y2;
int X3,Y3;
X1 = r00; Y1 = (g00+b00)/2;
X2 = (r00+b00)/2; Y2 = g00;
X3 = (r00+g00)/2; Y3 = b00;
sR(1,X1+0*W,Y1) = r00;
sG(1,X1+0*W,Y1) = g00;
sB(1,X1+0*W,Y1) = b00;
sR(1,X2+1*W,Y2) = r00;
sG(1,X2+1*W,Y2) = g00;
sB(1,X2+1*W,Y2) = b00;
sR(1,X3+2*W,Y3) = r00;
sG(1,X3+2*W,Y3) = g00;
sB(1,X3+2*W,Y3) = b00;
}
}
FreeImage_Save(FreeImage_GetFIFFromFilename(filename_o), dib1, filename_o);
FreeImage_DeInitialise();
printf ("Quit.\n");
return 0;
}
#!/bin/bash
NAME="clrgb"
gcc -g -o _$NAME $NAME.cpp -lfreeimage
./_clrgb smirenie-xxs011.jpg clrgb-test-output.png
Вот результат: http://php.kirovnet.ru/images/clrgb-test-output.png
Видно, что на третьей проекции - появились синие пиксели.
Их на исходном изображении нет.
Но в буфере data0 (при работе программы) они появляются:
$ ./_clrgb smirenie-xxs011.jpg clrgb-test-output.png
w: 570
h: 429
bpp: 3
stride: 1710
768 256 24
1 3 : 00 00 CD
3 6 : 00 00 C5
5 9 : 00 00 C7
7 12 : 00 00 C0
9 15 : 00 00 D1
11 18 : 00 00 C9
13 21 : 00 00 C3
15 24 : 00 00 CB
17 27 : 00 00 C1
19 30 : 00 00 B5
21 33 : 00 00 BE
23 36 : 00 00 9C
...
Потратил уже часа 4, чтобы понять проблему - почему они появляются. Есть идеи?
Пока думаю, что это - баг FreeImage.
Проверьте программу с картинкой у себя.