I need to use loadspritemem with jpg files, but this command needs the image size.
So, before loading the jpg file I need to know his size in pixels.
I found a doc at http://stackoverflow.com/questions/2517854/getting-image-size-of-jpeg-from-its-binary and it seems it is not that easy (it is not stored on the jpg header).
So I found this piece of code at http://www.64lines.com/jpeg-width-height but I have no idea how to insert it into GLB.
Anyone can help?
//Gets the JPEG size from the array of data passed to the function, file reference: http://www.obrador.com/essentialjpeg/headerinfo.htm
static char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height) {
//Check for valid JPEG image
int i=0; // Keeps track of the position within the file
if(data[i] == 0xFF && data[i+1] == 0xD8 && data[i+2] == 0xFF && data[i+3] == 0xE0) {
i += 4;
// Check for valid JPEG header (null terminated JFIF)
if(data[i+2] == 'J' && data[i+3] == 'F' && data[i+4] == 'I' && data[i+5] == 'F' && data[i+6] == 0x00) {
//Retrieve the block length of the first block since the first block will not contain the size of file
unsigned short block_length = data[i] * 256 + data[i+1];
while(i<data_size) {
i+=block_length; //Increase the file index to get to the next block
if(i >= data_size) return false; //Check to protect against segmentation faults
if(data[i] != 0xFF) return false; //Check that we are truly at the start of another block
if(data[i+1] == 0xC0) { //0xFFC0 is the "Start of frame" marker which contains the file size
//The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
*height = data[i+5]*256 + data[i+6];
*width = data[i+7]*256 + data[i+8];
return true;
}
else
{
i+=2; //Skip the block marker
block_length = data[i] * 256 + data[i+1]; //Go to the next block
}
}
return false; //If this point is reached then no size was found
}else{ return false; } //Not a valid JFIF string
}else{ return false; } //Not a valid SOI header
}
Here is my glb code that loads a JPG file (size known) and resize it by 50%
FUNCTION test2:
LOCAL pix%[],ok,w%,h%,x,y,tpix%[]
w%=5000;h=3000
ok=LOADSPRITEMEM("d:/8000.jpg",w,h,pix%[])
DIM tpix[((w*h)/4)]
ok=0
FOR y=0 TO h-1 STEP 2
FOR x=0 TO w-1 STEP 2
tpix[ok]=pix[(y*w)+x]
INC ok
NEXT
NEXT
ok=MEM2SPRITE(tpix[],1,w/2,h/2)
SAVESPRITE "d:/prueba.png",1
DRAWSPRITE 1,0,0
SHOWSCREEN
MOUSEWAIT
END
ENDFUNCTION
SPRTOMEM returns the sprites width and height in the second and third parameters...
But I need to load the sprites as "loadspritemem", and this function needs the size...
LOADSPRITE is limited to the max texture size of each device, so I need to scale down before passing them as sprites.
LOADSPRMEM load upto 5000x3000 pixels (in my test, a 15 megapixel image, not tested bigger); then I downscale the image and sent to a sprite bank to be used with MEM2SPRITE.
SPRITE2MEM is the reverse of what i want to do.
Hi Ampos...
I tried to do a nice code to check JPG image size but it's not fully functional :-[
OPENFILE (1,"test.jpg",1)
LOCAL data1%
LOCAL data2%
GLOBAL width%
GLOBAL height%
LOCAL bye=0
WHILE bye=0
READUBYTE 1,data1%
//search for 0xFF (255)
IF data1%=255
READUBYTE 1,data2%
//search for 0XC0 (192)
IF data2%=192
//we skips 3 bytes
READUBYTE 1,data1%
READUBYTE 1,data1%
READUBYTE 1,data1%
//now we get the height
READUBYTE 1,data1%
READUBYTE 1,data2%
height%=data1%+data2%
//now we get the width
READUBYTE 1,data1%
READUBYTE 1,data2%
width=data1%+data2%
bye=1
ENDIF
ENDIF
WEND
PRINT "width: "+width,10,10
PRINT "height: "+height,10,40
SHOWSCREEN
SLEEP 3000
This code is pretty slow and It only works for very small images (width / height under 128 pixels). I can't found a readxxxxxx command that suit the many bytes that you need to get the correct values for bigger images, but I'm sure that some guru here can help us.
Sorry again, I hope it helps anyway
Bye!
LOADSPRMEM will "RETURN" the image size. It would be stupid otherwise.
Quote from: Kitty Hello on 2011-Oct-29
LOADSPRMEM will "RETURN" the image size. It would be stupid otherwise.
Gernot, but LOADSPRMEM need the sprite/image size as param...
LOL, I though that this double % was a misstyping... :S
From the GLB help guide:
QuoteLOADSPRITEMEM()
ok% = LOADSPRITEMEM(file$, w%%, h%%, pixRGBA%[])
Loads a sprite not as graphics, but into an DIM array to be used e.g. with MEM2SPRITE later.