News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Help converting MASM code to C

Started by psyshadow, April 11, 2009, 03:14:15 AM

Previous topic - Next topic

psyshadow

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

ecube

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.

BogdanOntanu

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.

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

psyshadow

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.

ecube

Toss in a ExitProcess(0); before your return(0);

MichaelW

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?
eschew obfuscation

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

sinsi

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.
Light travels faster than sound, that's why some people seem bright until you hear them.

MichaelW

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.
eschew obfuscation

ecube

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.

Relvinian

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

drizz

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.
The truth cannot be learned ... it can only be recognized.

MichaelW

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.
eschew obfuscation

psyshadow

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.