Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / embeding media in EXE

Author
Message
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 3rd Apr 2008 13:00
Hi,

I need some help to embed some small gif and jpg files into the final EXE.

First step would be to convert the binary file into hex and end up with a c++ statement like this inside my code:

const unsigned char MyJpg[]={
0x37,0x61,0x30,0x00,0x39,0x00,0xf3,0x00,0x00,0xb2,0xc0,0xdc,
............................................................
0x7c,0x7d,0x40,0xc5,0x92,0x0c,0x34,0x39,0x41,0x04,0x00,0x3b
};

* How can I pass the handle of "MyJpg" to the DP command "MAKE IMAGE FROM MEMBLOCK" ?

any help would be greatly appreciated.
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 3rd Apr 2008 14:46
You do it the other way around. Get a memblock. Get the memblock pointer, and pass that to your C++ function, which simply uses memcpy to fill it with the data. Then make image from memblock.

The easiest way to get an image into the code in an array like that is to use your own code to open the image, and then write the text file out for you. Then, you open the text file and cut and paste the hardcoded data back into the program. Its alot of work to setup, but it is very helpful to the program, especially if you are talking about a large number of images that you want to protect using that type of scheme. It also works for creating data statements for doing the same thing in DBPro. It really improves load times, as well.
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 3rd Apr 2008 16:53
thanks jinzai for the tips. i now got a good idea of how it should work.

however i still cannot get it to compile. i am for sure missing something, somewhere, i think i have to declare "smileydata" somewhere...

any ideas would be greatly appreciated.

Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 3rd Apr 2008 17:35
Move your smileydata between the #include and the DarkGDK block. The compiler needs to know the existence of the data before it's referenced. That's why your code needs prototypes for functions if the function definitions follow the code where they're reference but not if the functions are defined before they're referenced.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 3rd Apr 2008 17:59
Aside from what Lilith just said, you must write the width, height and depth in the first 12 bytes for that to work. Also, be aware that you are putting integers into a byte array. What you have does not look like its done that, that would be an enormous image with an enormous bit depth.
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 3rd Apr 2008 18:15 Edited at: 3rd Apr 2008 18:18
Note that the data stored must be bitmap data, you can't just copy JPG data to a memblock and make an image from it, as it will be the wrong format.

Also note that doing this will increase the loading time of the EXE, along with doubling memory usage (and increasing disk usage due to not being able to store the image data compressed). I wouldn't recommend doing this.

bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 3rd Apr 2008 18:45
Benjamin,

if dbMakeImageFromMemblock needs bitmap data, then what does the command dbMakeBitmapFromMemblock exactly do?
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 3rd Apr 2008 18:51
It makes a bitmap from a memblock, which must contain bitmap data.

Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 3rd Apr 2008 19:04
Quote: "if dbMakeImageFromMemblock needs bitmap data, then what does the command dbMakeBitmapFromMemblock exactly do?"


I'm taking a guess here because I haven't seen it explicitly stated but, because bitmaps are supposed to be slower to use than images, I'm thinking that images are actually kept in the video buffers while bitmaps are kept in main memory. This would be because images are used as textures for sprites, which are essentially rectangular surfaces made up of two triangles. The video hardware should be handling these. The format of the image textures could be variable depending on the video card.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 3rd Apr 2008 20:25 Edited at: 3rd Apr 2008 20:31
Here is an executable that will make a text file for each jpg, bmp, tga and dds in a directory. These files are enormous, but in MSVC++, you can set the cursor where you want the data, and use insert file as text, and use the output of this app I am uploading. You should probably make an include file, and dump them all in that, then include it last in your main source file that uses it. The generated data is very large, I only put 12 bytes on a line at this time. Below is the DBPro source for the utility.

Another thing, gif and png do not work for different reasons. GIF is not supported as an image format, and pngs usually carry an alpha component and use a different bitmap structure. I will try to get that going, and I can dump GIF using my ImageMagick plug-in.

If you have interest in this utility, I will make it work for more formats.



This should work just fine, and will be faster than loading by conventional means, you just need to create the data in the proper format, which this utility is supposed to do.

To use it, put it in the same directory as the images, and run it. It will convert all the images in that directory.

Attachments

Login to view attachments
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 3rd Apr 2008 20:51 Edited at: 3rd Apr 2008 21:09
*dang* double post

Okay, Lilith...there are Device Independent Bitmaps, and Device Dependent Bitmaps. Much of what you are finding out experimentally is true, except that DDBs can be in system memory in Windows, I suppose that GDK does try to pass them into the GPU memory, but you could also keep DDBs in your program's memory. I'm not sure how much speed that would get you, or exactly how to implement it, but I will try to get you some answers, too.

If you have decent access to docs on the windows GDI and GDI++, you would learn alot from reading them, I think.
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 3rd Apr 2008 21:10
well done jinzai this tool looks really good.

i still can;t get my code running, especially since dbGetMemblockPtr() is passing a dword result and memcpy does not like that.

i thought this would be much simpler.

any other ideas?
Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 3rd Apr 2008 21:14
You may have to type cast the DWORD to a pointer.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 3rd Apr 2008 21:36 Edited at: 3rd Apr 2008 22:47
Yes, do what Lilith says. You'll get it going...soon.

(void *)ptr

EDIT: If you are using the dbGetMemblockPtr() in the memcpy call (which I wouldn't do, as I'll explain in a second...), you can cast it directly...
memcpy((void*)dbGetMemblockPtr(memblocknumber), (const void*)array_name, sizeof(array_name));

...but, you should get used to using local memory for returns from GDK. For one thing, I don't know if it still passes floats as DWORDS, and you need to get a little creative to use them.
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 4th Apr 2008 09:04
i only started using DBpro, DarkGDK and VC++ last week!

I already got many things going, but now I need to finalise enbedding pictures in the exe before moving on...
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 4th Apr 2008 10:43 Edited at: 4th Apr 2008 10:56
That's okay, you've already gotten farther than alot of people, and GDK is still new.

Let's get on the same page, and get it working. First, let me say that I am using DBPro and not GDK, but that should not matter as long as I remember that fact.

I have already modified that tool to output just the memblock, but that is not going to help your situation, but I am making it more flexible. I think it needs a GUI for starters.

What I said before is this: If you place those long arrays in one include file (call it myimages.h, or whatever suits you.), and then in your main source code file put this at the bottom of the other include files, you don't have to have all of that text cluttering up your main source file. Make sure that the include file is in the project directory...same place as the main source code file. The include statement would look something like this:
#include "myimages.h"

You can now make references to the arrays directly, and you will not have to load them from disk, just recopy them into a new image if necessary. To get the array into an image follow this general procedure:

dbMakeMemblock(availablemembloc, sizeof(myimage_jpg));
ptr = dbGetMemblockPtr(availablememblock)
memcpy((void*)ptr, (const void*)myimage_jpg, sizeof(myimage_jpg));
dbMakeImageFromMemblock(availablememblock, availableimage);
dbDeleteMemblock(availablememblock);

ptr is a DWORD. availablememblock and availableimage you can hard-code for now, but you'd usually want to get those by checking to see if the ID number you want is actually available at the time you want to use it. I usually start at 1, and call dbMemblockExist(valuetocheck), or whatever resource I am using...images work that way, too. You can probably get away with 1 for the imagenumber and the memblocknumber.

Now, imagenumber is available for you to paste like any other image, and whatever else you want to do with it.

I know a few things to minimize the effects that Benjamin mentioned, like loading the arrays in a part of the program's memory space that you can discard, for example.

So, try that out, and let me know what that gets for you. I have verified the RAW data output in DBPro...it works in DBPro, and I can use the embedded media option with compression, it packs up nicely, and you can also encrypt it, but that slows the load down. Besides, you can also encrypt it when you write the file, and use two memblocks to decrypt it after loading. (That's alot to say, I know...I just want you to realize that this way need not have negative effects...In fact, it should be relatively easy to use any of the memblock functions that same way.)
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 4th Apr 2008 15:15
Finally it works:



thanks to all especially jinzai for the great help!
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 4th Apr 2008 15:18
Quote: "What I said before is this: If you place those long arrays in one include file (call it myimages.h, or whatever suits you.), and then in your main source code file put this at the bottom of the other include files, you don't have to have all of that text cluttering up your main source file. Make sure that the include file is in the project directory...same place as the main source code file. The include statement would look something like this:
#include "myimages.h""


I tried to do this some time ago but can't manage it yet. I am reading as much as I can about C++ but sometimes, the most basic things elude you.

I know that you can divide your source in different files, so that you can resue it for different projects, but i don't know how to do that yet in vc++
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 4th Apr 2008 15:33
some statistics for those who are interested to include their media in exes:

smiley.jpg is 11k

above example exe with media embedded is 317k (after upx compression)

above example exe but loads smiley externally with dbLoadImage is 222k (after upx compression)

so there is an overhead of 84k.

for me this is not a big problem as in this one case i would prefer to have 1 exe that contains all the picture data necessary for the program to run standalone.
Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 4th Apr 2008 16:55
Quote: "I know that you can divide your source in different files, so that you can resue it for different projects, but i don't know how to do that yet in vc++"

Quite easy. If you create the .h file and then issue a #include "myheader.h" in the code it's net effect is as if you actually typed the code in that spot.

If you use double quotes around the name of the file it means a qualified path (usually the path the project source code is sitting in) or a fully qualified path if you so include it. If the name of the file is surrounded by angle brackets it tells the compiler to find the file amidst the include directories for the system or where you've defined them for the project.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 4th Apr 2008 21:27
Lilith I was doing exactly as you described but I couldn't get it work!

Now I tried again, and it worked! will never know what I was doing wrong!

This will help me a lot in my projects as I can split them in seperate sources!

fantastic!

thansk a lot
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 5th Apr 2008 09:45
Excellent news, I'm glad to be able to help you get it going. I am going to finish that tool up this weekend. I've got the PNG, TGA and GIF files in there now, and also PCX. I can add more...ImageMagick handles 154 formats. I also decided to put the const modifier on the array generated.

Cheers.
bjadams
AGK Backer
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 5th Apr 2008 16:29
thanks jinzai looking forward to your tool
Taoie
16
Years of Service
User Offline
Joined: 29th Mar 2008
Location:
Posted: 10th Apr 2008 20:55
smileydata[] = Array of what?
an image that convert to binary?

but if i have 3 picture how to do?

Login to post a reply

Server time is: 2024-11-20 07:29:08
Your offset time is: 2024-11-20 07:29:08