Image size in jpg files, need help with C code

Previous topic - Next topic

ampos

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?

Code (glbasic) Select
//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
}
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

ampos

Here is my glb code that loads a JPG file (size known) and resize it by 50%

Code (glbasic) Select
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
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

MrTAToad

SPRTOMEM returns the sprites width and height in the second and third parameters...

ampos

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.

check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

blackway

Hi Ampos...
I tried to do a nice code to check JPG image size but it's not fully functional  :-[

Code (glbasic) Select
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!




Kitty Hello

LOADSPRMEM will "RETURN" the image size. It would be stupid otherwise.

ampos

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...
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

ampos

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.





check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE