I have a weird image format here used in an embedded device, and as usual the documentation is not helping ...
Here are the two lines of doc:
The image is:
Full color bitmap (4+4+4bit per pixel), 3 bytes per two pixels (pixelorder from left to right).
So, in order to be able to get an image our of a sequence of bytes, I have coded the following:
// size_x and size_y are known at this point
QImage img(size_x, size_y, QImage::Format_RGB444);
int xctr = 0;
int yctr = 0;
for(int c1 = 0; c1 < bsize; ) // bsize is the size of image bytes
{
static const int M = 1; // a multiplier to make the image brighter
uint8_t b1 = *(p_pos + c1++); // p_pos points to the first image byte
uint8_t b2 = *(p_pos + c1++);
uint8_t b3 = *(p_pos + c1++);
uint8_t pix1_r =( (b1 & 0xF0) >> 4 ) * M;
uint8_t pix1_g =( (b1 & 0xF) ) * M;
uint8_t pix1_b =( (b2 & 0xF0) >> 4 ) * M;
uint8_t pix2_r =( (b2 & 0xF) ) * M;
uint8_t pix2_g =( (b3 & 0xF0) >> 4 ) * M;
uint8_t pix2_b =( (b3 & 0xF) ) * M;
// old code
//unsigned int pix1 = pix1_r << 8 | pix1_g << 4 | pix1_b;
//unsigned int pix2 = pix2_r << 8 | pix2_g << 4 | pix2_b;
// new code
unsigned int pix1 = ((unsigned int)pix1_r) << 8 | pix1_g << 4 | pix1_b;
unsigned int pix2 = ((unsigned int)pix2_r) << 8 | pix2_g << 4 | pix2_b;
// set the first pixel
img.setPixel(xctr, yctr, pix1);
xctr ++;
if(xctr == size_x) {
xctr = 0;
yctr ++;
}
// set the second pixel
img.setPixel(xctr, yctr, pix2);
xctr ++;
if(xctr == size_x) {
xctr = 0;
yctr ++;
}
}
And here is the image I get as a result from this:
And here is an image (very similar to what) I am supposed to get (only the blue/magenta parts, please don't consider the black background and the snow :) ):
For the brave ones, the image data: http://pastebin.com/m4y8qamB and please feel free to use this Python creating an array from hex bytes to convert the raw data to "real" hex bytes.
And the question: Now, ignoring the image palette, which is embedded in the device itself, what am I doing wrongly that I do not obtain a similar image to the one expected? And what should I do obtain a similar image?
Edit After adding some printout of the decoded values (and printing chars), I get something like:
PPPPPPPPPPPPPPPPPPPAPPPPPPPPPPPP
PPPPPPPAPPPPPPPPPPPPPPPPPPPAPPPP
PPPPPPPPPPPPPPPAPPPPPPPPPPPPPPPP
PPPAPPPPPPPPPPPPPPPPPPPAPPPPPPPP
PPPPPPPPPPPAPPPPPPPPPPPPPPPPPPPA
PPPPPPPPPPPPPPPPPPPAPPPPPPPPPPPP
PPPPPPPAPPPPPPPPPPPPPPPPPPPAPPPP
PGPPPPPPPPPPPPPAPPPPPCANMMMMMMMM
MMMMAMMMMOPCALDDDDDDDDDDDADDDMPC
ANODDDDDDDDDDDDADDKPANPCAGMMMMMM
MMMMMMAMMNPCANPCANPCANPCANPCANPC
ANPCANPPPAPPANPCANPCANPCANPCANPC
ANPCANPCADDADDPCANPCANPCANPCANPC
ANPCANPCANPCMMAMMMMMMMMMMMMMMMMM
MMAMMMMMMMMMMMMMMMMMMMAMMMMMMMMM
MMMMMMMMMMAMMMMMMMMMMMMMMMMMMMAM
MMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMM
MMMMMMAMMMMMMMMMMMMMMMMMMMAMMMMM
MMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMM
MMAMMMMMMMMMMMMMMMMMMMAMMMMMMMMM
I converted the pastebin data to a binary file using
perl -pe 's/([0-9a-f]{2})\s+/chr(hex($1))/ige' > tempfile
which seems correct when i look at the hex dump of that file.
Then i wrote a program to decode that file:
#include <stdio.h>
typedef unsigned char uint8_t;
#define M 1
int main(void) {
FILE *fp;
int sizex, sizey;
int xctr, yctr;
int i=0;
if ((fp=fopen("tempfile", "rb"))==NULL) {
perror("tempfile"); exit(1);
}
sizey=getc(fp);
sizex=getc(fp);
int bsize=getc(fp)*256;
bsize+=getc(fp);
xctr=yctr=0;
for (i=0; i<bsize/3; i++) {
uint8_t b1=getc(fp);
uint8_t b2=getc(fp);
uint8_t b3=getc(fp);
uint8_t pix1_r =( (b1 & 0xF0) >> 4 ) * M;
uint8_t pix1_g =( (b1 & 0xF) ) * M;
uint8_t pix1_b =( (b2 & 0xF0) >> 4 ) * M;
uint8_t pix2_r =( (b2 & 0xF) ) * M;
uint8_t pix2_g =( (b3 & 0xF0) >> 4 ) * M;
uint8_t pix2_b =( (b3 & 0xF) ) * M;
unsigned int pix1 = ((unsigned int)pix1_r) << 8 | pix1_g << 4 | pix1_b;
unsigned int pix2 = ((unsigned int)pix2_r) << 8 | pix2_g << 4 | pix2_b;
printf("%3x ", pix1);
xctr++;
if (xctr==sizex) {
putchar('\n');
xctr=0;
}
printf("%3x ", pix2);
xctr++;
if (xctr==sizex) {
putchar('\n');
xctr=0;
}
}
}
which does more or less what yours does, and has the output:
393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393
393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393
393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393
393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393
393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393 393
393 393 393 393 393 393 393 999 ddd eee bcc 393 393 999 fd0 2fd 02f d02 fd0 2f9 993 933 933 933 939 99f fd0 2fd
02f d02 fd0 2fd 02f ccc 666 ffd 02f d02 fd0 2fd 02f d02 fd0 2fd 029 993 933 933 93d ddf fd0 2fd 02f d02 fd0 2fd
02f d02 fd0 2ee eff d02 fd0 2fd 02f d02 fd0 2fd 02f d02 ddd 393 393 393 fd0 2fd 02f d02 bbb 393 bcc ffd 02f d02
fd0 1ee 393 393 bbb ffd 02f d02 f39 339 339 3fd 02f d02 fd0 239 339 339 3ee efd 02f 999 393 393 393 ffd 02f d02
f39 339 339 3fd 02f d02 fd0 2aa a39 399 9ff d02 fd0 2fd 01e e39 339 399 9ff d02 fd0 2f3 933 933 93d ddf fd0 2fd
02f d02 fd0 2fd 02f d02 fd0 2fd 02f d02 fd0 2fd 02f d01 eef d02 fd0 2fd 02d dd3 933 933 938 88f fd0 2fd 02f d02
fd0 2fd 02f aaa 999 ffd 02f d02 fd0 2fd 02f d02 fd0 2fd 029 993 933 933 933 938 88c ccc cc9 993 933 93a aaf d02
fd0 2fd 02f d02 f99 939 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339
339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339
339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339
339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339 339
which seems like the decoding process is ok, but the output still doesn't look like an image.
Looking at your original pastebin data again, i'm almost certain there's some error in that data. At the start, the sequence '39 33 93' repeats a few time, which translates nicely to 393 393. But later, you have 'FD 02 FD 02 FD 02 FD 02'. This would translate to 'FD0 2FD 02F D02 FD0 2..', i can't imagine that this is correct. Is it possible that some bytes are missing (like \\0 bytes not getting transferred) and the ending 339's are actually data that belongs to the next image?
I couldn't let the question rest ;) I noticed my file has 2F7 (hex) bytes, but the header says 02A0, so there must be something that's in the file but has to be ignored on output. Then, I had the idea of what happens if you omit all 'F' half bytes from the input (and omit the 393 from the output), but the result didn't look very nice, especially, the 39 33 93 was shifted sometimes to decode to 933 933 933.
Next, i omitted all F and E half bytes, resulting in this:
start of image
999 ddd bcc 999 d02 d02 d02 d02 999
999 d02 d02 d02 d02 d02 ccc 666 d02 d02 d02 d02 d02 d02
d02 999 ddd d02 d02 d02 d02 d02 d02 d02 d02 d02 d02
d02 d02 d02 d02 ddd d02 d02 d02 bbb bcc d02 d02
d01 bbb d02 d02 d02 d02 d02 d02
999 d02 d02 d02 d02 d02 aaa 999 d02
d02 d01 999 d02 d02 ddd d02 d02 d02 d02 d02
d02 d02 d02 d02 d02 d02 d01 d02 d02 d02 ddd 888 d02
d02 d02 d02 d02 aaa 999 d02 d02 d02 d02 d02 d02 d02 999
888 ccc ccc 999 aaa d02 d02 d02 d02 999
I'm now at 02df
end of image
which doesn't look completely correct, but much better than everything we had until now. I assume something more has to be omitted, since the code reads until 0x2df, not 0x2f7, but maybe this helps you in finding what else you have to do. Here's my code; note i read sizey first, then sizex, since this seems to yield a better picture:
#include <stdio.h>
typedef unsigned char uint8_t;
#define M 1
int sizex, sizey;
int xctr, yctr;
int main(void) {
FILE *fp;
int i=0, c;
int flag;
if ((fp=fopen("tempfile", "rb"))==NULL) {
perror("tempfile"); exit(1);
}
sizey=getc(fp);
sizex=getc(fp);
int bsize=getc(fp)*256;
bsize+=getc(fp);
xctr=yctr=0;
for (i=0; i<bsize*2;) {
c=getc(fp);
if ((c&0xf0) != 0xf0 && (c&0xf0) != 0xe0) {
push ((c>>4)&0x0f);
i++;
}
if ((c&0x0f) != 0x0f && (c&0x0f) != 0x0e) {
push (c&0x0f);
i++;
}
}
printf("I'm now at %04x\n", ftell(fp));
}
int push(int c) {
static int pos=0;
static uint8_t red, green, blue;
if (pos==0) { pos=1; red=c; }
else if (pos==1) { pos=2; green=c; }
else if (pos==2) { pos=0; blue=c; }
if (pos==0) {
if (red==3 && green==9 && blue==3)
printf(" ");
else
printf("%01x%01x%01x ", red, green, blue);
xctr++;
if (xctr==sizex) {
putchar('\n');
xctr=0;
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.