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 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!cyclone1.gnilink.net!spamkiller.gnilink.net!gnilink.net!nwrddc01.gnilink.net.POSTED!a5a7929f!not-for-mail Subject: Re: Representing image data Newsgroups: comp.lang.ada References: <9WAtl.2301$gm6.1634@nwrddc02.gnilink.net> From: ka@sorry.no.email (Kenneth Almquist) Message-ID: Date: Fri, 13 Mar 2009 20:31:18 GMT NNTP-Posting-Host: 96.242.119.89 X-Complaints-To: abuse@verizon.net X-Trace: nwrddc01.gnilink.net 1236976278 96.242.119.89 (Fri, 13 Mar 2009 16:31:18 EDT) NNTP-Posting-Date: Fri, 13 Mar 2009 16:31:18 EDT Xref: g2news1.google.com comp.lang.ada:4118 Date: 2009-03-13T20:31:18+00:00 List-Id: Here is my latest version of the row-at-a-time interface. First, sample values are best thought of as integer types rather than modular types, so we shouldn't use the Unsigned types from the Interfaces package even though they have the right type. Instead, we declare: type Sample_8 is range 0 .. 2**8 - 1; type Sample_16 is range 0 .. 2**16 - 1; The size of these types defaults to 8 and 16, respectively, so no size clauses are necessary. An application could use these types in to represent sample values throughout the application, or could perform type conversions on the individual samples. To make fetching rows type safe, we declare a generic package for each possible type. For example, to read an RGB image with 8 bits per sample, one could write: declare package Rows is new Imd.RGB_8(Decoder); Row : Rows.Row_Ptr; begin for Row_Number in 1 .. Decoder.Height loop Rows.Get_Row(Row); for Column_Number in Row.all'Range loop Store_Pixel(Row_Number, Column_Number, Row.all(Column_Number).Red, Row.all(Column_Number).Green, Row.all(Column_Number).Blue); end loop; end loop; end; The Store_Pixel routine is a stand-in for whatever processing the application wants to do on the pixel values. This code ignores the problem of error handling. The Get_Row procedure produces a pointer to the next row. It would be possible to make it produce the contents of the row rather than a pointer, but there doesn't seem to be a strong case for doing that. The application code would be marginally simpler because the references to "Row.all" would change to "Row". It would also be marginally slower because of the extra copying. The Imd.RGB_8 package is defined an implemented as follows: generic Decoder : Decoder_State; package Imd.RGB_8 is -- Elaborating an instantation of this package will initialize -- the decoding of the image sample data. pragma Elaborate_Body; type Pixel is record Red : Sample_8; Green : Sample_8; Blue : Sample_8; end record; pragma Pack(Pixel); type Row_Array is array (Integer range 1 .. Decoder.Width) of Pixel; type Row_Ptr is access all Row_Array; -- Get_Row - Get the next row. Each call to Get_Row generates a -- new row and returns a pointer to the row. If an error occurs, -- Get_Row will set the error flag in the Decoder structure and -- continue processing, producing row data that may not be meaningful. procedure Get_Row(Row : out Row_Ptr); pragma Inline(Get_Row); end Imd.RGB_8; -- generic -- Decoder : Decoder_State; package body Imd.RGB_8 is function Imd_Read_Row(Decoder : Decoder_State) return Row_Ptr; pragma Import(C, Imd_Read_Row, "imd_read_row"); procedure Imd_Start_Read(Decoder : Decoder_State); pragma Import(C, Imd_Start_Read, "imd_start_read"); procedure Get_Row(Row : out Row_Ptr) is begin Row := Imd_Read_Row(Decoder); end Get_Row; begin Imd.Set_Output_Format(Decoder, RGB + Size_8); Imd_Start_Read(Decoder); end Imd.RGB_8; We have to define a separate generic package for each pixel format and sample size. If the meaning of the samples is not known, the package to use is Imd.Any_8 or Imd.Any_16, which defines the pixel type as: type Pixel is array (Integer range 1 .. Decoder.Samples_Per_Pixel) of Sample_16; pragma Pack(Pixel); This package could be used for any image type. For mapped data, two generic instantiations are required declare package Map_Def is new Imd.Map_RGB_16(Decoder) package Rows is new Imd.Map_8(Decoder); Map : Map_Def.Map_Ptr; Row : Rows.Row_Ptr; begin Map_Def.Get_Map(Map); [loop through rows here] end; Using two generic instantiations reduces the number of generic packages required. The first defines the type of the map, and the second defines the type of the pixel samples that refer to the entries in the map. This scheme requires about 28 generic packages. Kenneth Almquist