Configurazione, organizzazione ed impostazione dell'oggetto Image secondo i sorgenti di Gambas

Da Gambas-it.org - Wikipedia.

Per la creazione di una "Image", non v'è la sola e semplice allocazione di memoria per la memorizzazione dei dati immagine in essa contenuti, ma, essendo anche un "Oggetto" di Gambas, si innesca una procedura più complessa che coinvolge più "Strutture" di dati a livello dei sorgenti di Gambas, e quindi diversi byte di memoria da occupare.

Tali risorse, insomma, servono sia per definire alcune caratteristiche generali dell'oggetto "Image", sia per memorizzare i dati immagine che essa contiene.

Vediamo, dunque, cosa avviene, appunto, a livello dei sorgenti di Gambas e quali loro risorse in particolare vengono richiamate e usate per creare e gestire una "Image".

La memorizzazione, dunque, dei dati immagine e di alcune caratteristiche dell'immagine caricata nell'Oggetto "Image", avviene attraverso l'utilizzo di una "Struttura", chiamata "GB_IMB ", così dichiarata nel file sorgente ".../main/lib/image/gb.image.h ":

typedef
       struct GB_IMG {
               GB_BASE ob;
               unsigned char *data;                      // points at the image data
               int width;                                // image width in pixels
               int height;                               // image height in pixels
               int format;                               // image format (RGB, BGR, RGBA...)
               GB_IMG_OWNER *owner;
               void *owner_handle;
               GB_IMG_OWNER *temp_owner;
               void *temp_handle;
               unsigned modified : 1;
               unsigned sync : 1;
               unsigned is_void : 1;
               }
       GB_IMG;

Laddove, con riferimento ai membri che ci interessano, abbiamo:

  • GB_BASE ob, rappresenta la Struttura GB_BASE, contenuta nel file sorgente ".../main/share/gambas.h" dell'Interprete. Il primo membro di tale Struttura GB_BASE è a sua volta un Puntatore alla Struttura chiamata CLASS e definita nel file sorgente ".../main/gbx/gbx_class.h".
  • unsigned char *data, rappresenta un Puntatore all'area di memoria contenente i dati grezzi dell'immagine caricata.
  • int width, è un Intero che rappresenta la dimensione in pixel della larghezza dell'immagine.
  • int height, è un Intero che rappresenta la dimensione in pixel dell'altezza dell'immagine.
  • int format, è un Intero che rappresenta il formato dell'immagine, come specificato nell'elenco delle definizioni del "Constants used by image data format", presente nel predetto file sorgente ".../main/lib/image/gb.image.h".


Accedere e leggere nella Struttura GB_IMG

E' possibile da un progetto Gambas penetrare nella Struttura "GB_IMG " e leggere i dati contenuti in alcuni suoi membri mediante due modalità che mostriamo di seguito.

Utilizzare solo Puntatori

Questa prima modalità prevede l'uso dei soli Puntatori per accedere e muoversi all'interno dell'area di memoria della Struttura "GB_IMG ", e dunque leggere i dati contenuti nei membri che ci interessano.
(E' necessario attivare il Componente "gb.image.io"; e si suggerisce di utilizzare una immagine di dimensione più piccola possibile per non congestionare la scrittura dei dati immagine grezzi in console. Inoltre, l'esempio funziona con sistema a 64-bit !).

Public Sub Main()
 
 Dim im As Image
 Dim p1, p2, p3 As Pointer
 Dim s As String
 Dim b As Byte
 Dim w, h, i, n As Integer
  
 im = Image.Load("/percorso/del/file/immagine")
   
 p1 = Object.Address(im)
   
' Accede alla Struttura CLASS
 p2 = Pointer@(p1)
 p3 = Pointer@(p2 + (SizeOf(gb.Pointer) * 3))
 s = String@(p3)
 Print s
     
' Dereferenzia il membro "int width"
 w = Int@(p1 + 24)
 Print w
   
' Dereferenzia il membro "int height"
 h = Int@(p1 + 28)
 Print h
   
' Dereferenzia il membro "int format"
 i = Int@(p1 + 32)
 Print i
 If (i < 4) Or (i > 5) Then i = 4
   
' Accede all'area di memoria puntata dal membro "unsigned char *data"
 p2 = Pointer@(p1 + (SizeOf(gb.Pointer) * 2))
' Dereferenzia ogni dato puntato in quel momento del ciclo dal Puntatore
 For n = 0 To (w * h * i) - 1
   Print Hex(Byte@(p2 + n), 2),
   If (n + 1) Mod 4 = 0 Then Print
 Next
  
End


Utilizzare anche una Struttura dichiarata in Gambas

La seconda modalità prevede, invece, l'uso di un Puntatore per il solo accesso all'area di memoria della Struttura, e la successiva assegnazione di tale Puntatore ad una Struttura dichiarata nel progetto Gambas di dimensioni e configurazione simili alla Struttura "GB_IMG ".
(E' necessario attivare il Componente "gb.image.io"; e si suggerisce di utilizzare una immagine di dimensione più piccola possibile per non congestionare la scrittura dei dati immagine grezzi in console).

Public Struct GB_BASE   ' Riproduce la Struttura annidata 'GB_BASE'
  klass As Pointer
  ref As Long
End Struct

Public Struct GB_IMG    ' Riproduce la Struttura 'GB_IMG'
  ob As Struct GB_BASE
  data As Pointer
  width As Integer
  height As Integer
  format_ As Integer
  owner As Pointer
  owner_handle As Pointer
  temp_owner As Pointer
  temp_handle As Pointer
  msi As Integer
End Struct


Public Sub Main()
 
 Dim im As Image
 Dim p As Pointer
 Dim img As GB_IMG
 Dim i, n As Integer
  
 im = Image.Load("/percorso/del/file/immagine")
   
 p = Object.Address(im)
   
' Assegna il "Puntatore" alla Struttura GB_IMG, così valorizzandola:
 img = p
  
 With img
   Print .width
   Print .height
   Print .format_
   If (.format_ < 4) Or (.format_ > 5) Then i = 4
   For n = 0 To (.width * .height * i) - 1
     Print Hex(Byte@(.data + n), 2),
     If (n + 1) Mod 4 = 0 Then Print
   Next
 End With
  
End


Note

[1] Si rinvia per identico argomento alle seguenti pagine della WIKI: