Loading Jpegs To DirectDraw Surfaces Loads the JPGE image file to the surface of DirectDraw
By Johnny Wood
Translation: SEA_BUG
The translator: This is an article on the use of Intel Jpges Library. While translating, the translator will properly add the articles according to its own experience, and hope to be suitable for readers.
In order to keep the size of this article down, I've decided to make a few assumptions. First of all, I assume somewhat familiar that you already know C / C and how to troubleshoot and debug code. I also assume that you are with DirectDraw and that you have as a minimum the DirectX 7.0 libraries and the ability to work in 24 bit Note:. the source code in EXAMPLE.ZIP available at the end of this article provides conversions to 16bit and 32bit surfaces.
In order to maintain the order in this article, I will decide to arrange some assumptions. First of all, I assume that you have learned that C / C is debugging the code. I also assume that you have some understanding of DirectDraw with the library files you get DirectX 7.0, and work in 24bit. Note: The original code included in this article
EXAMPLE.ZIP
The operation is provided to 16bit and 32 bit surfaces.
The first step to loading JPEGs is to download the Intel JPEG Library from Intel's website. The Library is loaded with documentation and examples, all of which we're really not interested in. What we really want are the IJL.H, IJL15.LIB , and IJL15.DLL files that come with the package. Once you have those files, include the IJL.H header to your source file, add the IJL15.LIB file to your project, and make sure the IJL15.DLL is in a valid Location Such as The C: / Windows / System Folder.
To load the JPGE image file, you should download Intel JPEG Library on the website of Intel, which contains development documents and routines, as well as what you are not interested. We really want ijl.h, ijl15.lib, and ijl15.dll files. Once you have these files, you contain ijl.h header to your code file, add ijl15.lib files to your project, and determine that ijl15.dll file is in a valid location, such as a C: / Windows / SysStem file. The clip, of course, can also be placed on the same folder with the program that we compile.
There Are A Few More Things We need to do before what we have a direct draw surface to work with: Some things need us ready before starting, we need to determine how we have workable DirectDraw surface :
LPDIRECTDRAWSURFACE7 SURFACE = NULL;
WE NEED TO Also Be Sure To Setur Display Bit Depth to 24 Bit:
We also need to set our video mode with a depth of 24bit:
DDOBJECT-> SetDisplayMode (640, 480, 24, 0, 0);
We're Now Ready to Load a Jpeg To Our Surface. Since We're Using The Intel Jpeg Library, We NEED TO CREATE A COUPLE OF Objects:
We are now ready to load the JPEG image to our surface, since we want to use Intel Jpeg Library, we need to create a connection object:
Ijlerr Jerr; JPEG_CORE_PROPERTIES JCPROPS;
Ijlerr Holds Return Information for DETERMING A Pass or Fail Status. JPEG_CORE_PROPERTIES ISUR JPEG Object. Once We Have these Two Objects, We Are Ready to Initialize Them:
Ijlerr saves the returned termination or error attribute information. JPEG_CORE_PROPERTIES is our JPEG object, once we have these two objects, we are ready to initialize them:
Jerr = ijlinit; if (jerr! = ijl_ok) // Report Initialization Error
.
ijlinit function call Initialize the JPEG_CORE_PROPERTIES object, we can detect this function call to test whether our IJLERR object is initializing whether the property is IJL_OK.
At this point, we must decide if we are going to load our JPEG image from a file or from a buffer. Because loading from a file takes fewer steps, we will do that here. However, I give an example of loading from both in THE End of this article. we load from a file by changing our jpeg Object's jpgfile me.....................
At this point, we must decide that we load our JPEG image from the file or from the data buffer. Because the steps need to be loaded from files, we will use this method. In any case, in the example of the article Example.zip, I will give two available methods. We load and convert our JPG file members to a file name from the file, and we call the IJLRead function to re-get the file parameters. JCPROPS.JPGFILE = filename; jerr = ijlread (& jcprops, IJL_JFILE_READPARAMS); if (Jerr! = IJL_OK) // Report Read Error
This initial read fills our JPEG object with information about the file we are going to load. What we must now do is find a way of converting the JPEG to a device independent bitmap (DIB) so that we can attach it to our Direct Draw surface .
This initially specifies the file name of our JPGE object, we will load it according to this. We must now look for a conversion method for JPGE devices and Bitmap (BID), so we can bind it to our DirectDraw surface.
WE Start by Creating a Buffer To Hold Our Image Data. After The Buffer Is Created, We Must Resize It To Fit A 24bit Image:
We start building a buffering to save our bitmap data. After this buffer is established, we must adjust the size to fit a 24bit bitmap:
// Prepare a 24Bit buffer to receive image dataBYTE * buffer24; // Determine the required sizelong szbuff24 = (jcprops.JPGWidth * 24 7) / 8 * jcprops.JPGHeight; // Resize the buffer and check for nullbuffer24 = new BYTE [ SZBuff24]; if (Buffer24 == Null) // Report Memory Allocation Error
Now We NEED TO FILL IN THE DIB Portion of the JPEG Object To Gety for the Conversion from JPEG To DIB.
Now we need to turn to the JPEG object to the part of the BID to populate.
jcprops.DIBWidth = jcprops.JPGWidth; jcprops.DIBHeight = jcprops.JPGHeight; // Implies a bottom-up DIB.jcprops.DIBChannels = 3; jcprops.DIBColor = IJL_BGR; jcprops.DIBPadBytes = IJL_DIB_PAD_BYTES (jcprops.JPGWidth, 3); JCPROPS.DIBBYTES = ReinterPret_cast
Let's look at some of these a little closer. The DIBBytes member points to the buffer that we created. When we retrieve the JPEG data, the information we get will be stored in this buffer. The DIBWidth and DIBHeight members specify the size of the DIB . The DIBColor member specifies that we want our image data in reverse order Blue Green Red that's the way that DIBs are actually stored They are also stored upside down You can flip the retrieved image by negating the DIBHeight member:... let's see Some of this structure, Dibbytes member variable points to a buffer we have established, when we re-get JPEG data, this information will be the buffer we used to store; DibWidth and Dibheight members specify the size of DIB; Dibcolor members specify that we want us to ask us Bitmap data is reversed or blue, green, red. That is the way DIBS actual storage, they are also stored, you can flip it:
// this is what you shop do if you find your imagehing out out upside down.jcprops.dibHeight = - jcprops.jpgheight;
Before We Read in The Image: The JPG Color Space:
Before we read the data, we also have to detect other things: JPG color space
// set the jpg color space ... this will always becomewhat of an // educated Guess At Best Because Jpeg IS "Color Blind" (IE, // Nothing in the bit stream tells you what color space the data WAS // encoded from.switch (jcprops.JPGChannels) {case 1: jcprops.JPGColor = IJL_G; break; case 3: jcprops.JPGColor = IJL_YCBCR; break; default: // This catches everything else, but no color twist will be // performed By the ijl. jcprops.dibcolor = (ijl_color) ijl_other; jcprops.jpgcolor = (ijl_color) ijl_other; Break;}
We are finally ready to retrieve the actual jpeg image. Thanks To Intel's Jpeg Library - this is a trivial task:
We are ready to finally get JPEG image data, thanking Intel's JPEG library - this is a very simple task:
// Read in image from filejerr = ijlRead (& jcprops, IJL_JFILE_READWHOLEIMAGE); if (! Jerr = IJL_OK) // Report read errorThis function copies the image information into our buffer At this point, if we were to insert a BITMAPFILEHEADER and a BITMAPINFOHEADER. at the front of our buffer, we could dump the buffer to a binary file. This would effectively create a bitmap file saved to disk. However, we instead want to turn our image into a DIB and attach it to a Direct Draw surface. Therefore We use the windows API Function CreateBitmap To Build Our Dib:
This function copy bitmap information to our buffer, in this place, if we are inserting a BitmapFileHeader or a BitmapInfoHeader to our buffer front, we can reverse into a binary, which will build a valid BMP on the disk Image file. In any case, we insert into the bitmap to rotate into a DIB and associate it on a surface of a DirectDraw. Therefore, we use the Windows API function CreateBitmap to build our DIB:
Hbitmap hbm; // create the bitmap and get a handeth to ithbm = createbitmap (jcprops.jpgwidth, jcprops.jpgheight, 1, 24, buffer24); if (hbm == null) // Report Failure to create bitmap
The CreateBitmap function takes the dimmensions of the image, the number of channels, the number of bits per pixel, and the color bit information from our bitmap buffer and creates a bitmap for us. Upon success, we are given a handle to the newly created Bitmap.
The task of the CreateBitMap function is to create a bitmap for us, including the number of channels, the number of pixels, the color bit information. On the basis of success, we get a new bitmap handle.
Before Go Any Further, WE NEED To Make Sure That We Have A Direct Draw Surface To Copy Our Bitmap To. Set Up Up Up Up Up Up Up The Direct Draw Surface Description and Create The Surface:
Before we entered a deeper level, we need to confirm that we have a surface of DirectDraw for our bitmap, set the DirectDraw surface structure and create a surface:
DDSURFACEDESC2 ddsd; ZeroMemory (& ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = jcprops.JPGWidth; ddsd. dwHeight = jcprops.JPGHeight; Result = DDObject-> CreateSurface (& ddsd, & Surface, NULL); if (! Result = DD_OK) // Report surface creation errorNow, all that is left is to copy our bitmap over to our Direct Draw surface. Fortunately, There is a function provided by Direct Draw That Does Just That. It can be found in the dduses.cpp file:
Now, copy our bitmaps to our DirectDraw surface, fortunately, if DirectDraw is just a function, it can be built in ddutils.cpp files:
DDCopyBitmap (Surface, HBM, 0, 0, 0, 0);
Before We Test Our Image Out, Let's Clean Up Some Things That We don't need NEED ANY more:
Before we test our bitmap, let us clean up something, it is not required:
// We no longer nesed outade bufferdelete buffer24; // Release the JPEG Objectijlfree (& JCPROPS);
Finally, The Time Has Come To Take Our Image For A Test Drive:
In the end, we test our bitmap:
RECT Image; // Reset surface descriptionZeroMemory (& ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); // Get the surface description so that we can dynamically // find the width and height of our surfaceResult = Surface- > GetSurfaceDesc; if (Result == DD_OK) {// coordinates of image size image.right = 0; image.top = 0; image.right = ddsd.dwwidth; image.bottom = ddsd.dwheight; // blit image to back buffer while (true) {Result = BackBuffer-> BltFast (0, 0, Surface, & Image, DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY); if (Result == DD_OK) break; if (Result == DDERR_SURFACELOST) {Result = RestoreAll (); if (! Result = DD_OK) break;} if break (Result = DDERR_WASSTILLDRAWING!);}} If everything goes smoothly, you should see your image pop up on the screen Keep in mind that you still have to release your. Surface when You No longer need it, and this allows RESTORE IT AS A RESULT OF Alt Tab. You Can R Estore The Surface By Following The Surface NOT NEED TO CREATE The Surface Again.
If everything is normal, you will have to see your bitmap is displayed on the screen, when you no longer need it, you still have to release your surface, or you need to recover the surface when you Alt Tab. You can restore the surface according to strict, you will not need to establish a surface again.
Good luck, And Have Fun with JPEGS!
I wish you good luck, and hope to use JPEGS to be happy! Intel JPEG LIBRARY can be downloaded in this site or download it on the INTEL official website.