Skip navigation
Currently Being Moderated

Code works on MacOs but doesn't on Windows

Feb 9, 2011 10:32 AM

Hi there,

I have another question.

 

This code exports the artboards in jpg with the a resolution of 300dpi. Everything works  on MacOs 10.6.6 and AI CS5.

I manage to export the jpg on Win 7 x64 and AI CS5 but can't manage to set any of the parameters in 1885434477 ('parm').

Is there anything special to do on Windows?

Thank you very much for your help.

 

typedef struct

{

    long quality;

    long kind;

    long scans;

    long antialias;

     AIFixed resolution;

    long colorModel;

    long alwaysTrue;

    long unused[18];

} jpegExportParametersCS5;

 

jpegExportParametersCS5 jpegExportParameters = {6,1,1,1,65535*300,3,1,1};

 

error = sAIActionManager->AIActionSetRawDataBytes(valueParameterBlock, 1885434477, (ASUInt32) sizeof(jpegExportParameters), (const char*) &jpegExportParameters);

 

error = sAIActionManager->PlayActionEvent("adobe_exportDocument", kDialogOff, valueParameterBlock);


 

 
Replies
  • Currently Being Moderated
    Feb 11, 2011 11:13 AM   in reply to benoitLagarde

    Try changing the dpi parameter to 300 << 16 rather than 300 * 65535, which is the proper way to convert to fixed.

     

    I'll keep looking to see if I see anything else.

     

    Brendon

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 11, 2011 11:19 AM   in reply to benoitLagarde

    I also just noticed that the struct you are using is different that the one we use. Where did you get this struct?

     

    Brendon

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 11, 2011 12:21 PM   in reply to benoitLagarde

    I think the problem is that while you have the length of the struct right, you can't just assume that the last 18 longs are unused. Here is the struct as we figured it out in CS4

     

     

    typedef struct JPGoptions

    {

         long quality; // 0-10, sucky to maximum

         long kind; // 0 = baseline, 1 = optimized, 2 = progressive

         long scans; // 1-3, actually means 3, 4 or 5

         AIBoolean antiAlias; // your choice

         AIFixed dpi; // short << 16

         long colorModel; // 1 = rgb, 2 = cmyk, 3 = gray

         int makeImageMap; // will always be true no matter what you set

         int mapType; // clientside = 0, serverside = 1

         char mapName[33];

         AIBoolean embedded;

    }JPGoptions;

     

     

    I notice that you have alwaysTrue where I have makeImageMap, which is the case (it will always be true). It's because of this that the image map name should be set. Just use "Unused ImageMap" or something like that. Windows should be happy with that.

     

    So much fun when working with undocumented structs :-)

     

    Brendon

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 11, 2011 12:32 PM   in reply to benoitLagarde
    I notice that If I record my export manually from the Mac and from the PC.

    I end up with the param 'parm' of a size of 100 bytes on the Mac and 104 bytes on the PC.

    Just wanted to chime in here and point out what is probably obvious -- the sizes are probably different since there are typedefs involved. I know that AIBoolean is very different between Mac & Windows (which is why I believe they use AIBool8 now). Even if you had the right structure in spirit, not having the right typedef for some of them could cause some odd structure alignment issues.

     

    And yes, undocumented structs are a lot of fun

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 11, 2011 4:01 PM   in reply to benoitLagarde

    You can pass 'parm', much easier to read. How are you defining valueParameterBlock? Maybe you could post the whole function.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 11, 2011 4:09 PM   in reply to benoitLagarde

    Also, it may not matter, but by convention I would pass sizeof(jpegExportParametersCS5) rather than sizeof(jpegExportParameters). Andrew will know if this matters or not.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 14, 2011 8:29 AM   in reply to Brendon Cheves

    Also, it may not matter, but by convention I would pass sizeof(jpegExportParametersCS5) rather than sizeof(jpegExportParameters). Andrew will know if this matters or not.

    The only typedef I know to be a problem is AIBoolean. It's basically ASBoolean (from ASTypes.h), which is typedef'd itself differently between Windows & Mac. On Windows, its an int, while on Mac its a unsigned char. So on Windows its 4 bytes and on Mac its 1 byte. I only noticed this because I ran into trouble with the ATE (it has a lot of boolean references for whether or not a text propetry is assigned) and I was getting strange results. I just checked CS3's SDK though, and they're already using AIBool8 by then, so they must have switched in CS3.

     

    Still, it's a potential source of trouble with a struct, unless the structs are actually different between Mac & Windows, in which case you'd have to have AIBoolean in there.

     

    I don't suppose you've done the record trick I've talked about on Windows? Namely, record the action you're looking at (in this case, Export JPEG) and then save the action set as an .AIA file. Now normally you'd be using this to get parameter information, but I recognized we're going to get an ugly block of binary. Still, if you do that trick on both Windows & Mac (with the same parameters), we might be able to compare the two and figure out if the structs are the same size or not. Either way, it'd tell us something I suspect. Might even be able to reverse engineer out the struct if the values are identifiable enough.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 14, 2011 12:56 PM   in reply to benoitLagarde

    Okay, assuming the struct looks like this (in order):

     

    long quality; // 0-10, sucky to maximum [4 bytes]

    long kind; // 0 = baseline, 1 = optimized, 2 = progressive [4 bytes]
    long scans; // 1-3, actually means 3, 4 or 5 [4 bytes]
    AIBoolean antiAlias; // your choice [4 bytes on Windows, 1 byte on Mac]
    AIFixed dpi; // short << 16 [long on both platforms, 4 bytes]
    long colorModel; // 1 = rgb, 2 = cmyk, 3 = gray [4 bytes]
    int makeImageMap; // will always be true no matter what you set [4 bytes]
    int mapType; // clientside = 0, serverside = 1 [4 bytes]
    char mapName[33]; [see below]
    AIBoolean embedded; [4 bytes on Windows, 1 byte on Mac]

    ------------------------------------------------

     

    0600000001000000030000000100000000002c01020000000100000000000000

    520061006300650054007200610063006b000000000000000000000000000000

    0000000000000000000000000000000000000000000000000000000000000000

    0000000001000000

     

    Becomes:

     

    06 00 00 00 - quality [6]
    01 00 00 00 - kind [optimized]
    03 00 00 00 - scans [5]
    01 00 00 00 - antiAlias [true]
    00 00 2c 01 - dpi [300]
    02 00 00 00 - colorModel [CMYK]
    01 00 00 00 - makeImageMap [true]
    00 00 00 00 - mapType [clientside]

    52 00 61 00 - R a
    63 00 65 00 - c e
    54 00 72 00 - T r
    61 00 63 00 - a c
    6b 00 00 00 - k

    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00

    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00

    00 00 00 00
    00 00 00 00 - this makes 68 bytes, which is 34 unicode characters, not 33 as one might expect

    01 00 00 00 - embedded [true]

     

    And

     

    0600000001000000020000000100000000002c01020000000100000001000000

    520061006300650054007200610063006b000000000000000000000000000000
    0000000000000000000000000000000000000000000000000000000000000000
    00000100

    Becomes:

     

    06 00 00 00 - quality [6]
    01 00 00 00 - kind [optimized]
    02 00 00 00 - scans [4]
    01 00 00 00 - anitAlias [true]
    00 00 2c 01 - dpi [300]
    02 00 00 00 - colorModel [CMYK]
    01 00 00 00 - makeImageMap [true]
    01 00 00 00 - mapType [serverside]

    52 00 61 00 - R a
    63 00 65 00 - c e
    54 00 72 00 - T r
    61 00 63 00 - a c
    6b 00 00 00 - k

    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00

    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00
    00 00 00 00

    00 00 00 00
    00 00 01 00 - oddity the '01' is probably the embedded, but the byte count is off

    A few notes:

     

    Given the layout of the string for mapName, I suspect its actually 33 unicode characters, not 33 char. Though there seems to be a difference between the Mac & Windows on the size of this field; it may be byte alignment, something I'm grossly uninformed on.

     

    Next, while some of the parameters are different (I'm not sure why, perhaps Benoit didn't quite make both actions exactly the same) they're pretty close. The major difference seems to be at the end. There are an extra four zeroes, but I think that actually makes two bytes. It could just be some kind of byte alignment or padding though.

     

    The fact that the Mac ends with 01 00 instead of 01 00 00 00 lends credence to the idea that there's a typedef at work here. I think that might be AIBoolean rearing its head and the Mac is aligning to four-bytes? I'm not sure. That would mean the first boolean (antiAlias) is actually only the first byte in the Mac breakdown and the next three bytes are filler. If its not that though, I'm at a loss to explain why 01 00 makes sense at the end, unless I've broken down the bytes very badly.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 14, 2011 1:16 PM   in reply to benoitLagarde

    The four-byte alignment does support my (admittedly shot-in-the-dark) theory. I'm afraid I know just enough about byte alignment to be a menace

     

    First, I don't think VS2010 is the problem. That really only becomes trouble if AI is passing you objects and you're deleting them, but they have a mostly C-style interface & Free*() methods for pretty much anything that looks like a handle. So I think you're safe there.

     

    I suspect its far more likely a problem with the char[33] member. It looks to me like that should be ASUnicode[33]. It could well be that working on the Mac is just a fluke.

     

    Out of curiosity, I know you're using sizeof() when you make the call to AIActionSetRawDataBytes(), but what does that actually return on each platform? I'm guessing you should see 104 & 100 as your results if the structs are setup right.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 14, 2011 1:58 PM   in reply to benoitLagarde

    Well, that struct is size 100, naturally, since you've got 7 longs and one array of 18 longs; that meaks 25 longs and since they're all 4 bytes, that's 100 bytes.

     

    Try this:

     

    typedef struct JPGoptionsModified

    {

         long quality;

         long kind;

         long scans;

         AIBoolean antiAlias;

         AIFixed dpi;

         long colorModel;

         int makeImageMap;

         int mapType;

         ASUnicode mapName[33];

         AIBoolean embedded;

    }JPGoptions;

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 14, 2011 2:08 PM   in reply to A. Patterson

    I just checked, and that struct is 104 bytes on Windows. I suspect its 100 on Mac, but I have no way to check right this minute.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 14, 2011 2:21 PM   in reply to benoitLagarde
    Can you enlight me and explain where the problem was?

    Should I also use the same struct on the mac?

     

    The problem was just the chars weren't chars. They were ASUnicode. They probaby were chars back in CS2 or CS3, but somewhere along the way they became unicode. I would try it on the Mac too, but check the sizeof() -- I suspect it will work out to be 100 as we'd expect.

     

    And I'm glad to hear its working!  Hopefully it will be fine on the Mac and this mystery will be solved. Frankly, this struct should be in an action header in the Actions folder of the SDK. I'm not sure why its not. Expecting us to reverse engineer action parameter's raw binary structs is asking a little much

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 2, 2012 4:07 PM   in reply to benoitLagarde

    Okay, so now that we are on CS6, using this:

    typedef struct JPGoptionsModified

    {

         long quality;

         long kind;

         long scans;

         AIBoolean antiAlias;

         AIFixed dpi;

         long colorModel;

         int makeImageMap;

         int mapType;

         ASUnicode mapName[33];

         AIBoolean embedded;

    }JPGoptions;

     

    produces the desired jpeg and ai files but also produces and extraneous .html file.  I have gotten this extraneous html file before when transitioning from one version to another and found it was due to using an incorrect parameter block, but I can't figure out how to make it right for cs6.  Everything seems to be the same except that "makeImageMap" and "mapType" seem to be switched. 

     

    ANY ideas??

     

    Here's a cs5 action export:

     

    /value < 100

                                            0a0000000200000003000000030000000000f401020000000 100000000000000

                                            55006e007400690074006c00650064002d003100000000000 000000000000000

                                            0000000000000000000000000000000000000000000000000 000000000000000

                                            00000100

                                  >

                                  /size 100

     

    And here's a cs6 action export:

     

    /value < 100

                                            0a0000000300000003000000030000000000f401020000000 000000001000000

                                            69006d006100670065006d006100700000003100000000000 000000000000000

                                            0000000000000000000000000000000000000000000000000 000000000000000

                                            00000100

                                  >

                                  /size 100

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points