From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,6d07d0186a356c56,start X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!news2.google.com!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!cyclone1.gnilink.net!spamkiller.gnilink.net!gnilink.net!nwrddc02.gnilink.net.POSTED!a5a7929f!not-for-mail Subject: Representing image data Newsgroups: comp.lang.ada From: ka@sorry.no.email (Kenneth Almquist) Message-ID: <9WAtl.2301$gm6.1634@nwrddc02.gnilink.net> Date: Tue, 10 Mar 2009 21:26:29 GMT NNTP-Posting-Host: 96.242.119.89 X-Complaints-To: abuse@verizon.net X-Trace: nwrddc02.gnilink.net 1236720389 96.242.119.89 (Tue, 10 Mar 2009 17:26:29 EDT) NNTP-Posting-Date: Tue, 10 Mar 2009 17:26:29 EDT Xref: g2news1.google.com comp.lang.ada:4022 Date: 2009-03-10T21:26:29+00:00 List-Id: I've been working on the design of an image decoding library. The basic idea is that the library will examine the first few bytes of an image, determine the format, and call the appropriate decoder, so that an application using the library can read images without writing code for each image format it wants to handle. I'm looking for suggestions on what the Ada interface to the library should look like--and in particular how the image contents should be provided to the application using the library. The current design has a C interface with no type checking on the image data. What follows is the C language interface presented in Ada syntax. The data for each pixel consists of one or more samples. There are a fair number of possibilities, because both the meaning of the samples and the number of bits per sample can vary. The possibilities for the meanings of the samples are: Imd.W - white (greyscale) sample Imd.WA - white + alpha (transparency) samples Imd.RGB - red + green + blue samples (color image) Imd.RGBA - RGB + alpha samples Imd.CMYK - C + M + Y + K samples (color printer separation) Imd.Unknown - one or more samples whose meaning is not known by the library. Any of the previous possibilities may be combined with Imd.Mapped. If Imd.Mapped is set, there is one sample per pixel representing an index into a color map. Each entry in the color map will contain one or more sample values, in one of the formats listed above. The size of the samples can be one of: Imd.Size_1BE Imd.Size_8 Imd.Size_16 Imd.Size_8 means that samples are 8 bits. The corresponding Ada type is Interfaces.Unsigned_8 or equivalent. Imd.Size_16 means 16 bit samples, stored in Interfaces.Unsigned_16 or equivalent. Imd.Size_1BE means one bit samples, packed into Unsigned_8 quantities in big endian order (high order bit first). Imd.Size_1BE is only used when there is one sample per pixel; it is intended to allow bit maps to be represented compactly. If a color map is used, then the size of the samples in the color map also needs to be specified. The possiblities are: Imd.Map_Size_8 Imd.Map_Size_16 In the C language interface, all of the above constants have the type Interfaces.Unsigned_16, and can be combined using the "+" or "or" operators. For example, mapped RGB color with 8 bit sample sizes can be specified as Imd.RGB or Imd.Mapped or Imd.Size_8 or Imd.Map_Size_8 Most applications would use only a few of the possible output formats. The library contains conversions to: - convert mapped data to unmapped data - convert greyscale to RGB. - convert CMYK to RGB (but not very accurately). - add or discard the alpha channel. - convert sample sizes to 8 or 16 bits. So the library can convert any image to (Imd.RGB or Imd.Size_8) except for images where the meanings of the samples are unknown. One additional variation is that the image can be decoded one row at a time, or in one piece. A row is represented as a sequence of pixel values, in left to right order. An image is represented as a sequence of rows, in top to bottom order. If the sample format is Imd.Size_1BE, then each row will be padded if necessary to make the size a multiple of 8, so that each row will start on a byte boundary. After processing the image header, the steps for decoding an image are: -- Set the output type. -- The variable Decoder is a pointer to the decoder structure. if Imd.Set_Output_Format(Decoder, Imd.RGB or Imd.Mapped or Imd.Size_8 or Imd.Map_Size_8) = False then Ada.Text_IO.Put_Line("Cannot convert to mapped RGB format"); raise ...; end if; -- Read the map (only do this for mapped output). declare type Map_Type is ...; type Map_Ptr is access all Map_Type; begin -- Allocate space for map. The Sizeof_Map routine calculates -- the correct size. Map_Ptr := malloc(Imd.Sizeof_Map(Decoder)); if Map_Ptr = null then raise Storage_Error; end if; -- Get the map. Imd.Get_Map(Decoder, Map_Ptr.all'Address); if Decoder.Error /= 0 then raise ...; end if; ... end; -- Read the entire image at once. declare type Image_Array is ...; type Image_Ptr is access all Image_Array; begin -- Allocate space for the image. Imd.Sizeof_Image calculates -- the correct size. Image_Ptr := malloc(Imd.Sizeof_Image(Decoder)); if Map_Ptr = null then raise Storage_Error; end if; -- Read the image. Imd.Get_Image(Decoder, Image_Ptr.all'Address); if Decoder.Error /= 0 then raise ...; end if; ... end; If the application wants to read one row at a time, it uses something like: -- Read the image, one row at a time. if Imd.Start_Output(Decoder) = False then Ada.Text_IO.Put_Line("Cannot decode image"); raise ...; end if; for Row_Number in 1 .. Decoder.Height loop declare type Row is ...; package Row_Acc is new System.Address_To_Access_Conversions(Row); Row_Ptr : Row_Acc.Object_Ptr; begin -- Read one row. Read_Row returns a pointer to the -- row, which is stored in a block of memory allocated -- by the library. Row_Ptr := Row_Acc.To_Pointer(Imd.Read_Row(Decoder)); ... end; end loop; -- Check for error. We could have done this inside the loop. if Decoder.Error /= 0 then raise ...; end if; For Imd.RGB + Imd.Size_8 output, the Row type could be declared as type Primary is (Red, Green, Blue); type Pixel is array (Primary) of Interfaces.Unsigned_8; type Row is array(1 .. Decoder.Width) of Pixel; But in C you would probably do the equivalent of type Row is array (Natural) of Interfaces.Unsigned_8; Thanks for any ideas. Kenneth Almquist