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 + 24)
     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 + 16)
' 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
  formati 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 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 .formati
    If (.formati < 4) Or (.formati > 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: