The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> C Programming
|
IJG: Jpeg to HBITMAP or JPeg use in general
Discuss IJG: Jpeg to HBITMAP or JPeg use in general in the C Programming forum on Dev Shed. IJG: Jpeg to HBITMAP or JPeg use in general C programming forum discussing all C derivatives, including C#, C++, Object-C, and even plain old vanilla C. These languages are low level languages, and used on projects such as device drivers, compilers, and even whole computer operating systems.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

March 13th, 2003, 04:49 PM
|
|
Junior Member
|
|
Join Date: Mar 2003
Posts: 6
Time spent in forums: < 1 sec
Reputation Power: 0
|
|
|
IJG: Jpeg to HBITMAP or JPeg use in general
Hello. First of all, I have been making use of the excellent tutorials here for some time.. but Im new to this forum. I read the rules thread and did a search on this topic.. so I apologize if I'm missing something obvious.
I am new to the winAPI.. I am working entirely in C.. and have been doing custom shaped windows and skinning them with bmp's for this project I am doing. But I would really like to reduce the size of the exe by using a jpeg resource instead of a bitmap.
I've downloaded and compiled the IGJ library.. and there is code in there I could use.. but Im having difficulties getting the image data into an HBITMAP. I have searched google high and low and am having problems finding any built in library.. and most '3rd party' libraries involve 2D or 3D graphics manipulation.. licensing fee's, demo versions.. ect.
I refuse to believe I am the first individual that has ever loaded a jpg into a windows program  , and I feel retarded that I can't figure out how everyone is doing it.
If someone could just point me in the right direction I would greatly appreciate it. Especially if I could stick with plain old C. We are trying to save every byte possible so we can email these programs to customers.
Thanks in advance.
|

March 13th, 2003, 05:36 PM
|
|
Contributing User
|
|
Join Date: Sep 2001
Location: ISRAEL
Posts: 35
Time spent in forums: < 1 sec
Reputation Power: 12
|
|
|
ok, you should understand some basics (and please correct me if i'm wrong):
- to load a bitmap to a reasource is as expensive as reading it from a file, or even more. (the size of the exe)
- if you will load the bitmap from a file at run time you decrease the size of the exe but you will have to send the bmp file together with the exe.
if you are not familiar with the API of reading from file i can explain.
basically, to load an image from a file use LoadImage()
(also relevant to pure C)
__________________
"Gravitation can NOT be responsible for people falling in Love"
(one of the most significant characters in the history, can you guess?)
Gmorph.
|

March 13th, 2003, 05:39 PM
|
|
Junior Member
|
|
Join Date: Mar 2003
Posts: 6
Time spent in forums: < 1 sec
Reputation Power: 0
|
|
|
Yeah.. I can load the image from a file just fine. I included it in the exe file for ease of distribution. The difficulty I am having is using a jpg file.
|

March 13th, 2003, 05:50 PM
|
|
Contributing User
|
|
Join Date: Sep 2001
Location: ISRAEL
Posts: 35
Time spent in forums: < 1 sec
Reputation Power: 12
|
|
|
i think that if the Jpeg is valid it should work well with HBITMAP but refer to MSDN for deeper description.
try:
BITMAP_FILE_HEADER
BITMAP_INFO
...
|

March 14th, 2003, 12:47 AM
|
|
Contributing User
|
|
Join Date: Oct 2000
Location: Back in the real world.
|
|
|
starting with W2K, jpegs are natively supported by the GDI. i.e. you should be able to load them directly via LoadBitmap(), but i never tried...
For making my programs work with all Windozes, I always use intelīs(? - the one that comes with Borland C++ Builder) jpeg library. There you can load a jpeg from a file and draw() them to any HDC. (i.e. also to a Bitmap or DIB) i donīt have any code around as i am at home, but if you can ask a more specific question, iīll gladly try to help.
M.
|

March 14th, 2003, 01:28 AM
|
|
Contributing User
|
|
Join Date: Oct 2000
Location: Back in the real world.
|
|
|
UPDATE: I found my sources...
I just found the sources on a backup CD. I am using IJGīs library too.
using jpeg_read_scanlines(), you can decompress the jpeg line by line to a bitmapīs bitmap-data.
the full process is quite complicated and many lines. And as i am using Delphi version and not C, i am not willing to translate all that right now. But i could post the relevant delphi code if you want... just tell me.
|

March 14th, 2003, 10:39 AM
|
|
Junior Member
|
|
Join Date: Mar 2003
Posts: 6
Time spent in forums: < 1 sec
Reputation Power: 0
|
|
|
It looks like Intel isn't offering their jpg package anymore. Its now part of thier IPP package you have to purchase.
So IJG it is. If I'm going to work scanline to scanline, don't I need to invert the image? That is.. aren't bmp's stored from bottom to top?
|

March 14th, 2003, 11:02 AM
|
|
|
|
I think the native support of JPEG images only works with a printer DC.
|

March 14th, 2003, 01:00 PM
|
|
Contributing User
|
|
Join Date: Oct 2000
Location: Back in the real world.
|
|
3dfxMM: possible. as said, i never tested it since my software needs to work with older windozes too.
grunt:
Quote: | don't I need to invert the image? That is.. aren't bmp's stored from bottom to top? |
so? how hard would it be to read the scanlines top to bottom and write bottom to top?
But i canīt remember this strange behaviour on BMPs, could be that Delphi hides it from the user though...
|

March 14th, 2003, 01:34 PM
|
|
Junior Member
|
|
Join Date: Mar 2003
Posts: 6
Time spent in forums: < 1 sec
Reputation Power: 0
|
|
Quote: | so? how hard would it be to read the scanlines top to bottom and write bottom to top? |
I wasn't commenting on difficulty.. but trying to clarify what would need to be done. I recall some of the IJG code reversing the scanlines for a bmp conversion.. and difficult or not, its somewhat important to get the pixel data correct.
I think I can organize thier code well enough. If there aren't well known libraries or methods.. I guess my question becomes, how would one create/modify an HBITMAP with this data?
|

March 14th, 2003, 01:49 PM
|
|
Contributing User
|
|
Join Date: Oct 2000
Location: Back in the real world.
|
|
Quote: | its somewhat important to get the pixel data correct. |
of course it is
Quote: | how would one create/modify an HBITMAP with this data? |
Just as you would do with any other bitmap too...
Code:
pseudocode:
ptr=CreateBitmap(width, height)
bmpsize=width*height*bpp // bpp=bytes per pixel
ptr+=sizeof(BITMAP_INFO)+bmpsize;
for (i=0;i<height;i++)
jpeg_read_scanlines(jc->d, ptr-i*width*bpp, 1);
not syntax-checked nor logic-checked. probably needs several "+/-1" somewhere. probably all wrong and will blow up your whole PC. i take no responsibility for nothing
Anyone got the time for making real code of this?
|

April 4th, 2003, 03:11 PM
|
|
Junior Member
|
|
Join Date: Mar 2003
Posts: 6
Time spent in forums: < 1 sec
Reputation Power: 0
|
|
well.. I found an easier way than converting the image scanline by scanline:
PHP Code:
HBITMAP ReadJpegFile( LPSTR pFile )
{
HANDLE hFile;
HBITMAP hBmp;
DWORD dwSize;
DWORD dwRead;
HGLOBAL hMemJpeg;
LPSTREAM lpStream;
OLE_HANDLE hJpegBmp;
HRESULT hr;
LPPICTURE lpPicture = NULL;
void *pMemJpeg;
/* Open the file and get the size. */
if((hFile = CreateFile(pFile, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
return NULL;
if((dwSize = GetFileSize(hFile, NULL)) == 0xFFFFFFFF)
{
CloseHandle(hFile);
return NULL;
}
/* Allocate space for file, read it in, and then close the file again. */
if((hMemJpeg = GlobalAlloc(GMEM_MOVEABLE, dwSize)) == NULL)
{
CloseHandle(hFile);
return NULL;
}
if((pMemJpeg = GlobalLock(hMemJpeg)) == NULL)
{
CloseHandle(hFile);
GlobalFree(hMemJpeg);
return NULL;
}
if(!ReadFile(hFile, pMemJpeg, dwSize, &dwRead, NULL))
{
CloseHandle(hFile);
GlobalFree(hMemJpeg);
return NULL;
}
CloseHandle(hFile);
GlobalUnlock(hMemJpeg);
/* Create the stream and load the picture. */
if((hr = CreateStreamOnHGlobal(hMemJpeg, TRUE, &lpStream)) != S_OK)
{
GlobalFree(hMemJpeg);
return NULL;
}
if(OleLoadPicture(lpStream, dwSize, FALSE, &IID_IPicture, &lpPicture) != S_OK)
{
GlobalFree(hMemJpeg);
lpStream->lpVtbl->Release(lpStream);
return NULL;
}
/* Get the handle to the image, and then copy it. */
if((lpPicture->lpVtbl->get_Handle(lpPicture, &hJpegBmp)) != S_OK)
{
GlobalFree(hMemJpeg);
lpStream->lpVtbl->Release(lpStream);
lpPicture->lpVtbl->Release(lpPicture);
return NULL;
}
if((hBmp = CopyImage((HANDLE *) hJpegBmp, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)) == NULL)
{
GlobalFree(hMemJpeg);
lpStream->lpVtbl->Release(lpStream);
lpPicture->lpVtbl->Release(lpPicture);
return NULL;
}
/* Free the original image and memory. */
GlobalFree(hMemJpeg);
lpStream->lpVtbl->Release(lpStream);
lpPicture->lpVtbl->Release(lpPicture);
return hBmp;
} /* End of ReadJpegFile(). */
But now Im having issues loading the image from my resources instead of an external file. Im really not very good with the winAPI. Any ideas?
|

April 5th, 2003, 01:08 PM
|
|
Junior Member
|
|
Join Date: Mar 2003
Posts: 11
Time spent in forums: < 1 sec
Reputation Power: 0
|
|
|

April 14th, 2003, 08:53 AM
|
|
Junior Member
|
|
Join Date: Apr 2003
Posts: 1
Time spent in forums: < 1 sec
Reputation Power: 0
|
|
Grunt are you looking for this? I was having some trouble doing it the right way with targa so I knew if I'll make it with bmp sure I will with tga. Anyway, one thing to remember jpeg library decodes the buffer with a sequence of RGB but bitmap RGBtag is flipped to BGR and the whole data are written flipped upside down.
int encode_bmp(char * inbuf, int width, int height, int components)
{
BITMAPFILEHEADER fheader;
BITMAPINFOHEADER iheader;
unsigned int extrabytes, bytesize;
memset(&fheader, 0, sizeof(BITMAPFILEHEADER));
memset(&iheader, 0, sizeof(BITMAPINFOHEADER));
extrabytes = (4 - (width * 3) % 4 ) % 4;
bytesize = (width * 3 + extrabytes) * height;
iheader.biSize = sizeof(BITMAPINFOHEADER);
iheader.biWidth = width;
iheader.biHeight = height;
iheader.biPlanes = 1;
iheader.biCompression = BI_RGB;
iheader.biBitCount = components * 8;
iheader.biSizeImage = bytesize;
fheader.bfType = ((WORD)('M' << 8) | 'B');
fheader.bfSize = 0; // can be 0 for BI_RGB
fheader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
File p("c:/somedirectory/somefile.bmp");
if(!p.open(File::write_binary))
{
return 0;
}
p.write(&fheader, sizeof(fheader));
p.write(&iheader, sizeof(iheader));
struct tag
{
unsigned char r, g, b;
};
tag t;
int pitch = width * components;
for(int j = (height * pitch - pitch); j >= 0; j-= pitch)
{
for(int i = j; i < j + pitch ; i+= components)
{
t.r = (unsigned char)inbuf[i + 2];
t.g = (unsigned char)inbuf[i + 1];
t.b = (unsigned char)inbuf[i ];
p.write(&t, sizeof(tag));
}
}
p.close();
return 1;
}
This code works.
Well anyway, I've got a different problem but I see right now no way to solve it. I probably missed something inside the library but I've been wandering a week and see no solution. Can anyone tell me how to initialize the destination manager by hand NOT using as a destination a file handle but only a buffer. Just a memory to memory jpeg coding. Been searching the web up and down, nowhere to find it  )) just like grunt was. One finds tons of examples doing it the easy way where the destination is always a FILE * but this is not my case. Thank you for ANY tips. Nice day/night/whatever....
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|