Hi there, I asked a previous question but I didn't explain it well enough; so sorry in advance for posting another similar question here also.
Quite simply, I need help converting the following MASM code to C, so that it works. Since this is the MASM forums I'm sure everyone here knows MASM and I'm sure the majority of you also know C.
You can leave out all the 'PRINT's in the following code also.
So to clarify: I need help converting this code to C Thanks so much in advance!
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
include \masm32\include\gdiplus.inc
includelib \masm32\lib\gdiplus.lib
include \masm32\macros\ucmacros.asm
GdiplusStartupInput STRUCT
GdiplusVersion DWORD ?
DebugEventCallback DWORD ?
SuppressBackgroundThread DWORD ?
SuppressExternalCodecs DWORD ?
GdiplusStartupInput ENDS
ImageCodecInfo STRUCT
ClassID CLSID <>
FormatID GUID <>
CodecName DWORD ?
DllName DWORD ?
FormatDescription DWORD ?
FilenameExtension DWORD ?
MimeType DWORD ?
Flags DWORD ?
Version DWORD ?
SigCount DWORD ?
SigSize DWORD ?
SigPattern DWORD ?
SigMask DWORD ?
ImageCodecInfo ENDS
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
token dd 0
image dd 0
numEncoders dd 0
sizeImageCodecInfo dd 0
pImageCodecInfo dd 0
gdipsi GdiplusStartupInput <1> ; version must be 1
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
print "GdiplusStartup rv "
invoke GdiplusStartup, ADDR token, ADDR gdipsi, NULL
print ustr$(eax),13,10
print "GdipLoadImageFromFile rv "
invoke GdipLoadImageFromFile, uni$("sample.bmp"), ADDR image
print ustr$(eax),13,10
print "GdipGetImageEncodersSize rv "
invoke GdipGetImageEncodersSize, ADDR numEncoders,
ADDR sizeImageCodecInfo
print ustr$(eax),13,10
print "numEncoders "
print ustr$(numEncoders),13,10
print "sizeImageCodecInfo "
print ustr$(sizeImageCodecInfo)," bytes",13,10
mov pImageCodecInfo, alloc(sizeImageCodecInfo)
print "GdipGetImageEncoders rv "
invoke GdipGetImageEncoders, numEncoders, sizeImageCodecInfo,
pImageCodecInfo
print ustr$(eax),13,10
xor ebx, ebx
mov esi, pImageCodecInfo
.WHILE ebx < numEncoders
invoke crt_printf, chr$("%S%c"), [esi].ImageCodecInfo.MimeType, 10
.IF ucmp$([esi].ImageCodecInfo.MimeType, uni$("image/jpeg") )
print "GdipSaveImageToFile rv "
invoke GdipSaveImageToFile, image, uni$("sample.jpg"),
esi, NULL
print ustr$(eax),13,10
.ENDIF
add esi, SIZEOF ImageCodecInfo
inc ebx
.ENDW
print "GdipDisposeImage rv "
invoke GdipDisposeImage, image
print ustr$(eax),13,10
print "GdiplusShutdown rv "
invoke GdiplusShutdown, token
print ustr$(eax),13,10
free pImageCodecInfo
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
You know you can just compile that as a few kilobyte static link library and use that right in your C program right? Either way I don't see where you would get confused in converting that to C. I'm the sure the struct are already defined, and rest is just callin api functions.
The conversion is straightforward and very simple.
If you are not able to perform it then maybe it is time to dedicate "more time" to learning C basics like how to declare variables, main(), functions, arguments, using "&", struc and typedefs.
Sorry but here we are concerned more with ASM than with C. Maybe you should try again on an C forum for C related questions (for example Pelle's C forum) and an ASM forum (here) for ASM related questions?
Many of our forum members are also experienced C programmers (like myself) but no offense I would not take the time to write/solve basic C code requests on an ASM forum ;)
Let us know if you have any ASM questions.
I appreciate the comments, but I won't be able to ever sleep again unless I can figure out why this code won't work. Since no one took the 11 minutes required to convert this, I'll just post what you most likely would have come up with:
#include <windows.h>
struct GdiplusStartupInput
{
DWORD GdiplusVersion;
DWORD DebugEventCallback;
DWORD SuppressBackgroundThread;
DWORD SuppressExternalCodecs;
};
struct ImageCodecInfo
{
CLSID ClassID;
GUID FormatID;
DWORD CodecName;
DWORD DllName;
DWORD FormatDescription;
DWORD FilenameExtension;
DWORD MimeType;
DWORD Flags;
DWORD Version;
DWORD SigCount;
DWORD SigSize;
DWORD SigPattern;
DWORD SigMask;
};
static DWORD token = 0;
static DWORD image = 0;
static DWORD numEncoders = 0;
static DWORD sizeImageCodecInfo = 0;
static DWORD pImageCodecInfo = 0;
static struct GdiplusStartupInput gdipsi = {1, 0, 0, 0};
int main()
{
GdiplusStartup(&token, &gdipsi, NULL);
GdipLoadImageFromFile(L"sample.bmp", &image);
GdipGetImageEncodersSize(&numEncoders, &sizeImageCodecInfo);
pImageCodecInfo = malloc(sizeImageCodecInfo);
GdipGetImageEncoders(numEncoders, sizeImageCodecInfo, pImageCodecInfo);
GdipSaveImageToFile(image, L"copy.bmp", pImageCodecInfo, NULL);
GdipDisposeImage(image);
GdiplusShutdown(token);
free(pImageCodecInfo);
return(0);
}
The problem is that once I get this far, the code WORKS, it copies a BMP like it's supposed to... But when the program exits there is an error. I have no idea why and I wish someone would just compile this and use their master debugging skills with their wonderful copy of IDA pro or something and say "Oh yeah, there's a memory leak because you don't declare the pointer properly." Oh okay, thanks, you are my hero!
Something along these lines. I appreciate the fact that all of you here are more focused on assembly, super, but if someone wanted to convert something from MASM to C and was having a little problem, I don't see the big deal.
Thanks so much again if anyone can help,
James.
Toss in a ExitProcess(0); before your return(0);
James,
There is no error that I can detect. Since you apparently know how to build this, instead of expecting us to take our time to figure out how (more than an hour in my case), why not post the necessary command lines?
James,
The bottom line is that this is an assembler forum, not a free code conversion facility, if you need assistance doing conversions you should try "Rent A Coder". Someone here may help you if they can be bothered but I would not hold your breath or attempt to impose any imperatives here.
Quote
Something along these lines. I appreciate the fact that all of you here are more focused on assembly, super, but if someone wanted to convert something from MASM to C and was having a little problem, I don't see the big deal.
The "big deal" is this, if you need to produce C code, go to a C code forum or perhaps try and get support from the compiler manufacturer, this is simply the wrong place for what you are after.
Some of us don't even know C *gasp* and don't want to (except to figure out .h files ::))
Quote from: psyshadow on April 12, 2009, 08:13:19 PM
Since no one took the 11 minutes required to convert this, I'll just post what you most likely would have come up with:
Since you can read our minds, why bother in the first place?
I could convert it to VB6 code if you like, since it's all API calls. Probably figure out how to do it in C, too.
You're welcome.
Instead of letting my time on this go to waste:
I was not able to use the GDI+ related header files from the PSDK. No matter what I tried, there were always errors, and in most cases many errors. For example, CL would choke on the first namespace declaration it encountered in gdiplus.h. Microsoft does not recommend calling the GDI+ Flat API directly - they want you to call it indirectly using .PIG or similar.
I was using Visual C++ Toolkit 2003 with the environment set up like this:
Set PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;%PATH%
Set INCLUDE=C:\Program Files\Microsoft SDK\include;%INCLUDE%
Set LIB=C:\Program Files\Microsoft SDK\lib;%LIB%
And my working command lines were:
cl /Gz /c gdip.c
link gdip.obj gdiplus.lib user32.lib
/Gz forces the __stdcall calling convention, and gdiplus.lib and user32.lib are import libraries from the PSDK. There were several warnings due to the use of DWORD, but nothing to stop the build. And user32.lib was required only because I added:
MessageBox( 0,0,"OK",0);
As a stdcall-compatible method of avoiding an immediate exit.
MichaelW,
I've been a C/C++ programmer for many years now, the issues you're having is common not just with Visual Studio but most C/C++ compilers/environments i've tried(i'm not talking about GDI+ but compiler issues ingeneral). This kind of thing is what makes MASM,GoASM etc.. so refreshing, the SDK's are small installs, does the same thing C/C++ does(and some things it can't) and it's almost guarenteed the code will assemble assuming paths are in order.
psyshadow,
I didn't quote your whole code but from what I have compiled and tested, you need to make sure you are using the correct MIME type. Like PNG / JPEG / BMP, etc. You are getting the Image Codec info but really are ignoring it. Check some examples on the Web to see how to make sure you set the correct type before writing out your file. That's the only thing I can see which may be causing internal problems in the Win32 API calls for GDI+.
For example, your code below uses an possibly BAD data about a codec. The 3rd parameter is actually suppose to be the CLSID of the MIME image type you want to use. ;-)
Quote
GdipSaveImageToFile(image, L"copy.bmp", pImageCodecInfo, NULL);
Hope this helps you with getting farther.
Relvinian
MichaelW,
Gdiplus is all c++, there is no c support at all.
psyshadow,
Where are your function prototypes? If you forgot to prototype them as __stdcall that would lead to stack corruption.
Quote from: drizz on April 14, 2009, 03:32:01 PM
Gdiplus is all c++, there is no c support at all.
Yes, but the Flat API is callable from C, and it could be done easily if suitable header files were available.
Thanks to everyone for posting and everything. I got it working with just an ExitProcess(0).. Heh.. I feel like a fool.. But yeah I only had to go this method in the first place because using the Platform SDK from Microsoft is a big headache it's all just a bunch of wrappers and classes to use GDI+. The code I used is in no way pretty, in fact it's horrible to have to mess around with code so much when trying to use microsofts API's. But yeah, it's all good now.
And sorry again for posting here for MASM to C conversion type stuff, but I just went by averages and common sense. If I post on a C board the amount of assembly users there are probably less than 1 in 100 (C users that know asm) versus assembly users where probably 1 in 2 know C.
Thanks again, it's nice to see that there are a few people on these boards that actually care to help.
James.