Jump to content
dummzeuch

converting a C enum to Delphi

Recommended Posts

Given the following C type definition:


 

/** image pixel layout information*/
typedef enum VmbPixelLayout
{
    VmbPixelLayoutMono,
    VmbPixelLayoutMonoPacked,
    VmbPixelLayoutRaw,
    VmbPixelLayoutRawPacked,
    VmbPixelLayoutRGB,
    VmbPixelLayoutBGR,
    VmbPixelLayoutRGBA,
    VmbPixelLayoutBGRA,
    VmbPixelLayoutYUV411,
    VmbPixelLayoutYUV422,
    VmbPixelLayoutYUV444,
    VmbPixelLayoutMonoP,
    VmbPixelLayoutMonoPl,
    VmbPixelLayoutRawP,
    VmbPixelLayoutRawPl,
    VmbPixelLayoutYYCbYYCr411,
    VmbPixelLayoutCbYYCrYY411 = VmbPixelLayoutYUV411,
    VmbPixelLayoutYCbYCr422,
    VmbPixelLayoutCbYCrY422 = VmbPixelLayoutYUV422,
    VmbPixelLayoutYCbCr444,
    VmbPixelLayoutCbYCr444 = VmbPixelLayoutYUV444,

    VmbPixelLayoutLAST,
}VmbPixelLayout;
typedef VmbUint32_t VmbPixelLayout_t;

Am I right in assuming that the following constants are an equivalent?

const
  VmbPixelLayoutMono = 0;
  VmbPixelLayoutMonoPacked = 1;
  VmbPixelLayoutRaw = 2;
  VmbPixelLayoutRawPacked = 3;
  VmbPixelLayoutRGB = 4;
  VmbPixelLayoutBGR = 5;
  VmbPixelLayoutRGBA = 6;
  VmbPixelLayoutBGRA = 7;
  VmbPixelLayoutYUV411 = 8;
  VmbPixelLayoutYUV422 = 9;
  VmbPixelLayoutYUV444 = 10;
  VmbPixelLayoutMonoP = 11;
  VmbPixelLayoutMonoPl = 12;
  VmbPixelLayoutRawP = 13;
  VmbPixelLayoutRawPl = 14;
  VmbPixelLayoutYYCbYYCr411 = 15;
  VmbPixelLayoutCbYYCrYY411 = VmbPixelLayoutYUV411;
  VmbPixelLayoutYCbYCr422 = 9; // is this correct?
  VmbPixelLayoutCbYCrY422 = VmbPixelLayoutYUV422;
  VmbPixelLayoutYCbCr444 = =10; // is this correct?
  VmbPixelLayoutCbYCr444 = VmbPixelLayoutYUV444;

I am in particular usure about the ones following those entries with an explicit value assignment, marked with the "// is this correct?" comment above.

I think that enums in C work like this:

typedef enum bla
{
zero, // start counting at 0
one, // 1
two, // 2
three, // 3
eins = one, // reset counter to 1
zwei, // 2
drei, // 3
}

So, every time a value is explicitly assigned to an enum the current counter is reset.

 

In case that matters: The declaration is from VmbTransformTypes.h, part of the Vimba ImagesTransform library for Microsoft Visual C(++).

 

 

Share this post


Link to post

Delphi actually supports C-style enums, although they are supposed to be used only in code that needs to interface with  C Dlls. The  compiler creates no RTTI for them, so they cannot be used in published properties, for instance. But this compiles without problem:

 

type
  VmbPixelLayout = (
    VmbPixelLayoutMono,
    VmbPixelLayoutMonoPacked,
    VmbPixelLayoutRaw,
    VmbPixelLayoutRawPacked,
    VmbPixelLayoutRGB,
    VmbPixelLayoutBGR,
    VmbPixelLayoutRGBA,
    VmbPixelLayoutBGRA,
    VmbPixelLayoutYUV411,
    VmbPixelLayoutYUV422,
    VmbPixelLayoutYUV444,
    VmbPixelLayoutMonoP,
    VmbPixelLayoutMonoPl,
    VmbPixelLayoutRawP,
    VmbPixelLayoutRawPl,
    VmbPixelLayoutYYCbYYCr411,
    VmbPixelLayoutCbYYCrYY411 = VmbPixelLayoutYUV411,
    VmbPixelLayoutYCbYCr422,
    VmbPixelLayoutCbYCrY422 = VmbPixelLayoutYUV422,
    VmbPixelLayoutYCbCr444,
    VmbPixelLayoutCbYCr444 = VmbPixelLayoutYUV444,

    VmbPixelLayoutLAST
    );

 

Share this post


Link to post

You can read the C standard to find out how it handles that enum. Then double check with a compiler.

 

I mean you surely aren't going to commit this without double checking with a C compiler? 

Edited by David Heffernan

Share this post


Link to post
1 hour ago, PeterBelow said:

Delphi actually supports C-style enums, although they are supposed to be used only in code that needs to interface with  C Dlls. The  compiler creates no RTTI for them, so they cannot be used in published properties, for instance. But this compiles without problem:

 


type
  VmbPixelLayout = (
    VmbPixelLayoutMono,
    VmbPixelLayoutMonoPacked,
    VmbPixelLayoutRaw,
    VmbPixelLayoutRawPacked,
    VmbPixelLayoutRGB,
    VmbPixelLayoutBGR,
    VmbPixelLayoutRGBA,
    VmbPixelLayoutBGRA,
    VmbPixelLayoutYUV411,
    VmbPixelLayoutYUV422,
    VmbPixelLayoutYUV444,
    VmbPixelLayoutMonoP,
    VmbPixelLayoutMonoPl,
    VmbPixelLayoutRawP,
    VmbPixelLayoutRawPl,
    VmbPixelLayoutYYCbYYCr411,
    VmbPixelLayoutCbYYCrYY411 = VmbPixelLayoutYUV411,
    VmbPixelLayoutYCbYCr422,
    VmbPixelLayoutCbYCrY422 = VmbPixelLayoutYUV422,
    VmbPixelLayoutYCbCr444,
    VmbPixelLayoutCbYCr444 = VmbPixelLayoutYUV444,

    VmbPixelLayoutLAST
    );

 

Unfortunately that won't compile: Delphi does not allow duplicate values in these enums.

Share this post


Link to post
34 minutes ago, dummzeuch said:

Unfortunately that won't compile: Delphi does not allow duplicate values in these enums.

Embarcadero's documentation says otherwise:

 

Enumerated Types with Explicitly Assigned Ordinality

 

Quote

Hence, given the declaration:


type SomeEnum = (e1, e2, e3 = 1);

SomeEnum has only two possible values: Ord(e1) returns 0, Ord(e2) returns 1, and Ord(e3) also returns 1; because e2 and e3 have the same ordinality, they represent the same value.

 

Edited by Remy Lebeau
  • Like 2

Share this post


Link to post

Couldn't you use a normal Delphi enum (i.e. without assignments) for the "main" values and define the extraneous ones as untyped constants?

Share this post


Link to post
3 hours ago, uligerhardt said:

Couldn't you use a normal Delphi enum (i.e. without assignments) for the "main" values and define the extraneous ones as untyped constants?

No, the ordinal values must be correct. These numbers are passed as parameters to a DLL written in C.

Share this post


Link to post
4 hours ago, Remy Lebeau said:
4 hours ago, dummzeuch said:

Unfortunately that won't compile: Delphi does not allow duplicate values in these enums.

Embarcadero's documentation says otherwise

OK, maybe that changed in later versions. I'm sure I tried that and it didn't compile.

But all that is syntactic sugar. I need to know about the values of

8 hours ago, dummzeuch said:

 

VmbPixelLayoutYCbYCr422 and VmbPixelLayoutYCbCr444.

Share this post


Link to post
4 hours ago, dummzeuch said:

But all that is syntactic sugar. I need to know about the values of

VmbPixelLayoutYCbYCr422 and VmbPixelLayoutYCbCr444.

In both C/C++ and Delphi, enums begin at 0, and values are sequential, unless explicitly otherwise stated.

 

Since VmbPixelLayoutYCbYCr422 and VmbPixelLayoutYCbCr444 do not have explicit values, they are implicitly +1 from the values they immediately follow.  Thus:

 

VmbPixelLayoutYCbYCr422 = VmbPixelLayoutCbYYCrYY411 (= VmbPixelLayoutYUV411 = 8 ) + 1 = 9

 

VmbPixelLayoutYCbCr444 = VmbPixelLayoutCbYCrY422 (= VmbPixelLayoutYUV422 = 9 ) + 1 = 10

 

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post
12 hours ago, dummzeuch said:

No, the ordinal values must be correct. These numbers are passed as parameters to a DLL written in C.

See for example https://www.geeksforgeeks.org/enumeration-enum-c/

If i understand that correctly the ordinals should be

 

type
  VmbPixelLayout = (
    VmbPixelLayoutMono,        {0}
    VmbPixelLayoutMonoPacked,  {1}
    VmbPixelLayoutRaw,         {2}
    VmbPixelLayoutRawPacked,   {3}
    VmbPixelLayoutRGB,         {4}
    VmbPixelLayoutBGR,         {5}
    VmbPixelLayoutRGBA,        {6}
    VmbPixelLayoutBGRA,        {7}
    VmbPixelLayoutYUV411,      {8}
    VmbPixelLayoutYUV422,      {9}
    VmbPixelLayoutYUV444,      {10}
    VmbPixelLayoutMonoP,       {11}
    VmbPixelLayoutMonoPl,      {12}
    VmbPixelLayoutRawP,        {13}
    VmbPixelLayoutRawPl,       {14}
    VmbPixelLayoutYYCbYYCr411, {15}
    VmbPixelLayoutCbYYCrYY411 = VmbPixelLayoutYUV411, {8}
    VmbPixelLayoutYCbYCr422,                          {9}
    VmbPixelLayoutCbYCrY422 = VmbPixelLayoutYUV422,   {9}
    VmbPixelLayoutYCbCr444,                           {10}
    VmbPixelLayoutCbYCr444 = VmbPixelLayoutYUV444,    {10}

    VmbPixelLayoutLAST        {11}
    );

which shows that the person that extended the enum after the RawP1 element did not understand the rules, since VmbPixelLayoutLAST is now definitely not the highest value in the enumeration.

Share this post


Link to post

OK, so my original translation was correct. Thanks everybody.

 

Regarding using Delphi enums:

typedef VmbUint32_t VmbPixelLayout_t;

is used in the function and struct declarations.

Yes, I could also change that too and use {$Z4} or {$MINENUMSIZE 4} to ensure that the enum size is at least 4 byte (but can I be sure that they aren't larger? (ever?)), but I'm not sure it's worth it. For now I'll simply go forward keeping it a Unit32, since I need something working as fast as possible.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×