Differenze tra le versioni di "Decomprimere un file immagine jpeg per ottenerne i dati grezzi mediante le funzioni esterne del API di libjpeg"

Da Gambas-it.org - Wikipedia.
(Creata pagina con 'Il formato ''JPEG'' (Joint Photographic Experts Group) è uno standard di compressione delle immagini, arrivando a ridurre le dimensioni di un file immagine anche sino al 5%. ...')
 
 
(2 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
Il formato ''JPEG'' (Joint Photographic Experts Group) è uno standard di compressione delle immagini, arrivando a ridurre le dimensioni di un file immagine anche sino al 5%.
 
Il formato ''JPEG'' (Joint Photographic Experts Group) è uno standard di compressione delle immagini, arrivando a ridurre le dimensioni di un file immagine anche sino al 5%.
  
E' possibile ottenere da un file immagine ''JPEG'' i suoi dati in formato grezzo utilizzando alcune funzioni della libreria esterna (nella sua attuale versione): ''libjpeg.so.8.0.2''.
+
E' possibile ottenere da un file immagine ''JPEG'' i suoi dati in formato grezzo utilizzando alcune funzioni della libreria condivisa: "''libjpeg.so.8.2.2'' ".
 
 
  
 
Mostriamo di seguito un esempio di decodifica di un file ''JPEG'', nel quale utilizzeremo - al fine di gestire con sicurezza una parte di codice - istruzioni in linguaggio C che saranno poste in un'apposita libreria esterna da noi creata.
 
Mostriamo di seguito un esempio di decodifica di un file ''JPEG'', nel quale utilizzeremo - al fine di gestire con sicurezza una parte di codice - istruzioni in linguaggio C che saranno poste in un'apposita libreria esterna da noi creata.
 
+
<BR>Il progamma mostrerà anche alcune informazioni di carattere generale sul file ''JPEG'' caricato.
Tale liberia ''ad hoc'' sarà così scritta:
+
  Library "libjpeg:8.2.2"
#include <stdio.h>
 
#include <stdlib.h>
 
#include <jpeglib.h>
 
 
 
unsigned char * bmp_buffer;
 
 
 
unsigned char *  Legge_linee(struct jpeg_decompress_struct * cinfo, int bmp_size, int row_stride) {
 
 
  bmp_buffer = (unsigned char*) malloc(bmp_size);
 
 
  while (cinfo->output_scanline < cinfo->output_height) {
 
 
    unsigned char *buffer_array[1];
 
 
    buffer_array[0] = bmp_buffer + (cinfo->output_scanline) * row_stride;
 
 
    jpeg_read_scanlines(cinfo, buffer_array, 1);
 
 
}
 
 
  return bmp_buffer;
 
 
 
}
 
 
 
Nel nostro esempio tale sorgente della libreria esterna verrà salvato con il nome ''libadhoc.c'' nella cartella ''Dati'' del progamma principale scritto in Gambas.
 
 
 
 
 
Il progamma principale scritto in Gambas, che mostrerà anche alcune informazioni di carattere generale sul file ''JPEG'' caricato, potrà avere il seguente tenore:
 
  Library "libjpeg:8.0.2"
 
 
   
 
   
 
  <FONT Color=gray>' ''struct jpeg_error_mgr * jpeg_std_error(struct jpeg_error_mgr * error_mgr)''
 
  <FONT Color=gray>' ''struct jpeg_error_mgr * jpeg_std_error(struct jpeg_error_mgr * error_mgr)''
Riga 68: Riga 36:
 
   
 
   
 
   
 
   
 +
<FONT Color=gray>' ''unsigned char *  Legge_linee(struct jpeg_decompress_struct * cinfo, int bmp_size, int row_stride)''
 +
' ''Invoca la libreria externa appositamente creata per leggere le righe di pixel del file JPEG.''</font>
 
  Private Extern Legge_linee(cinfo_ptr As Pointer, bmp_buf As Pointer, row As Integer) As Pointer In "/tmp/libadhoc"
 
  Private Extern Legge_linee(cinfo_ptr As Pointer, bmp_buf As Pointer, row As Integer) As Pointer In "/tmp/libadhoc"
 
   
 
   
Riga 78: Riga 48:
 
   Dim dim_jpg, dim_bmp As Long
 
   Dim dim_jpg, dim_bmp As Long
 
   Dim fl As File
 
   Dim fl As File
   Dim prog_riga, width, height, dim_pixel, rc As Integer
+
   Dim prog_riga, width, height As Integer
 +
  Dim num_comp, dim_pixel, rc As Integer
 
   Dim buffer, buf, bb As Byte[]
 
   Dim buffer, buf, bb As Byte[]
 
   
 
   
+
  <FONT Color=gray>' ''Crea la libreria esterna condivisa .so appositamente scritta:''</font>
  <FONT Color=gray>' ''Creiamo la libreria esterna condivisa .so da noi scritta:''</font>
+
  Creaso()
   Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared -fPIC -ljpeg" Wait
+
    
+
  percorso = "<FONT Color=gray>''/percorso/del/file/immagine.jpg''</font>"
+
  If Not Exist(percorso) Then Error.Raise("Percorso file immagine inesistente !")
  percorso = "''/percorso/del/file/immagine.jpg''"
+
  Print "File immagine JPEG: ", Null; percorso
  Print "File immagine JPEG: ", Null; percorso
 
 
   
 
   
 
  <FONT Color=gray>' ''Carica i dati jpeg da un file in un buffer di memoria:''</font>
 
  <FONT Color=gray>' ''Carica i dati jpeg da un file in un buffer di memoria:''</font>
  dim_jpg = Stat(percorso).Size
+
  dim_jpg = Stat(percorso).Size
  Print "Dimensione del file: ", Null; dim_jpg; " byte"
+
  Print "Dimensione del file: "; dim_jpg; " byte"
 
  fl = Open percorso For Read
 
 
   
 
   
  With buffer = New Byte[dim_jpg]
+
  fl = Open percorso For Read
    .Read(fl, 0, buffer.Max)
 
  End With
 
 
   
 
   
  fl.close()
+
  With buffer = New Byte[dim_jpg]
 +
    .Read(fl, 0, buffer.Max)
 +
  End With
 
   
 
   
 +
  fl.close()
 
   
 
   
  mgr = Alloc(168)
+
  mgr = Alloc(Sizeof(gb.Byte), 168)
  cinfo = Alloc(656)
+
  cinfo = Alloc(Sizeof(gb.Byte), 656)
 
    
 
    
  st = Memory cinfo For Write
+
  st = Memory cinfo For Write
  Write #st, jpeg_std_error(mgr) As Pointer
+
  Write #st, jpeg_std_error(mgr) As Pointer
 
   
 
   
  jpeg_CreateDecompress(cinfo, 80, 656)
+
  jpeg_CreateDecompress(cinfo, 80, 656)
 
    
 
    
  jpeg_mem_src(cinfo, buffer, dim_jpg)
+
  jpeg_mem_src(cinfo, buffer, dim_jpg)
 
   
 
   
  rc = jpeg_read_header(cinfo, True)
+
  rc = jpeg_read_header(cinfo, True)
  If rc <> 1 Then Error.Raise("Il file non sembra essere un normale JPEG !")
+
  If rc <> 1 Then Error.Raise("Il file non sembra essere un normale JPEG !")
 
    
 
    
 
  <FONT Color=gray>' ''Comincia la decompressione dei dati JPEG:''</font>
 
  <FONT Color=gray>' ''Comincia la decompressione dei dati JPEG:''</font>
  jpeg_start_decompress(cinfo)
+
  jpeg_start_decompress(cinfo)
 
    
 
    
  Seek #st, 48
+
  Seek #st, 48
  Read #st, width
+
  Read #st, width
  Print "Larghezza in pixel: ", Null; width
+
  Print "Larghezza in pixel: "; width
  Read #st, height
+
  Read #st, height
  Print "Altezza in pixel: ", Null; height
+
  Print "Altezza in pixel:   "; height
  Seek #st, 56
+
  Read #st, num_comp
  Read #st, dim_pixel
+
  Read #st, dim_pixel
  Print "Byte per pixel: ", Null; pixel_size; " (profondità: "; dim_pixel * 8; " bit)"
+
  Print "Byte per pixel:     "; num_comp; " (profondità: "; dim_pixel * 8; " bit)"
  st.Close
+
  st.Close
    
+
 
  dim_bmp = width * height * dim_pixel
+
   dim_bmp = width * height * dim_pixel
  Print "Dimensione bitMap: ", Null; dim_bmp; " byte\n"
+
  Print "Dimensione bitMap:   "; dim_bmp; " byte\n"
 
    
 
    
 
  <FONT Color=gray>' ''La variabile "prog_riga" è il numero totale di byte che serve per memorizzare un'intera linea di scansione (riga):''</font>
 
  <FONT Color=gray>' ''La variabile "prog_riga" è il numero totale di byte che serve per memorizzare un'intera linea di scansione (riga):''</font>
  prog_riga = width * dim_pixel
+
  prog_riga = width * dim_pixel
 
<FONT Color=gray>' ''Al termine della decompressione, si va a leggere tutte le linee di scansione del jpeg,''
 
' ''le quali di norma risultano disposte con l'ordine RGBRGBRGB (ordine che può essere cambiato agendo sul membro "cinfo.out_color_space"):''</font>
 
  bmp = Legge_linee(cinfo, dim_bmp, prog_riga)
 
 
   
 
   
  jpeg_finish_decompress(cinfo)
+
<FONT Color=gray>' ''Al termine della decompressione, si va a leggere tutte le linee di scansione del jpeg, le quali di norma risultano disposte con l'ordine RGBRGBRGB (ordine che può essere cambiato agendo sul membro "cinfo.out_color_space"):''</font>
   
+
  bmp = Legge_linee(cinfo, dim_bmp, prog_riga)
  jpeg_destroy_decompress(cinfo)
 
 
   
 
   
 +
  jpeg_finish_decompress(cinfo) 
 +
  jpeg_destroy_decompress(cinfo)
 +
<FONT Color=gray>' '''''''''''''''''''''''''''''''''''''''''''</font>
 
    
 
    
 
  <FONT Color=gray>' ''Ottenuti i dati grezzi, possiamo utilizzarli, ad esempio creando un file immagine non compresso (in questo caso di formato [[Struttura_e_gestione_del_file_di_tipo_PNM#Il_formato_PPM|PNM]]):''</font>
 
  <FONT Color=gray>' ''Ottenuti i dati grezzi, possiamo utilizzarli, ad esempio creando un file immagine non compresso (in questo caso di formato [[Struttura_e_gestione_del_file_di_tipo_PNM#Il_formato_PPM|PNM]]):''</font>
  fl = Open "/tmp/file.ppm" For Create
+
  fl = Open "/tmp/file.ppm" For Create
 
 
  st = Memory bmp For Read
 
  bb = New Byte[dim_bmp]
 
  bb.Read(st)
 
 
    
 
    
  header = "P6 " & CStr(width) & " " & CStr(height) & " 255\n"
+
  st = Memory bmp For Read
 +
  bb = New Byte[dim_bmp]
 +
  bb.Read(st)
 
    
 
    
  With buf = Byte[].FromString(header)
+
  header = "P6 " & CStr(width) & " " & CStr(height) & " 255\n"
    .Insert(bb)
 
    .Write(fl)
 
  End With
 
 
    
 
    
 +
  With buf = Byte[].FromString(header)
 +
    .Insert(bb)
 +
    .Write(fl)
 +
  End With
 
   
 
   
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
  st.Close
+
  st.Close
  fl.Close
+
  fl.Close
  Free(cinfo)
+
  Free(cinfo)
  Free(mgr)
+
  Free(mgr)
 +
 +
'''End'''
 
   
 
   
 +
'''Private''' Procedure Creaso()
 +
 
 +
<FONT Color=gray>' ''Imposta il codice sorgente della parte in linguaggio C:''</font>
 +
  File.Save("/tmp/libadhoc.c", "#include <stdio.h>\n#include <stdlib.h>\n#include <jpeglib.h>\n\n" &
 +
            "unsigned char * bmp_buffer;\n\n" &
 +
            "unsigned char *  Legge_linee(struct jpeg_decompress_struct * cinfo, int bmp_size, int row_stride) {\n\n" &
 +
            "  bmp_buffer = (unsigned char*) malloc(bmp_size);\n\n" &
 +
            "  while (cinfo->output_scanline < cinfo->output_height) {\n" &
 +
            "    unsigned char *buffer_array[1];\n" &
 +
            "    buffer_array[0] = bmp_buffer + (cinfo->output_scanline) * row_stride;\n" &
 +
            "    jpeg_read_scanlines(cinfo, buffer_array, 1);\n  }\n\n" &
 +
            "  return bmp_buffer;\n\n}")
 +
 
 +
<FONT Color=gray>' ''Crea la libreria esterna condivisa .so appositamente scritta per gestire la parte in linguaggio C:''</font>
 +
  Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared -fPIC -ljpeg" Wait
 +
 
 
  '''End'''
 
  '''End'''
 
  
  

Versione attuale delle 18:58, 1 dic 2021

Il formato JPEG (Joint Photographic Experts Group) è uno standard di compressione delle immagini, arrivando a ridurre le dimensioni di un file immagine anche sino al 5%.

E' possibile ottenere da un file immagine JPEG i suoi dati in formato grezzo utilizzando alcune funzioni della libreria condivisa: "libjpeg.so.8.2.2 ".

Mostriamo di seguito un esempio di decodifica di un file JPEG, nel quale utilizzeremo - al fine di gestire con sicurezza una parte di codice - istruzioni in linguaggio C che saranno poste in un'apposita libreria esterna da noi creata.
Il progamma mostrerà anche alcune informazioni di carattere generale sul file JPEG caricato.

Library "libjpeg:8.2.2"

' struct jpeg_error_mgr * jpeg_std_error(struct jpeg_error_mgr * error_mgr)
' Update the given jpeg_error_mgr object with standard error handling methods.
Private Extern jpeg_std_error(error_mgr As Pointer) As Pointer

' void jpeg_CreateDecompress(j_decompress_ptr cinfo, int version, size_t size)
' Allocate and initialize a JPEG decompression object of type struct jpeg_decompress_struct.
Private Extern jpeg_CreateDecompress(cinfo_ptr As Pointer, version As Integer, size As Integer)

' void jpeg_mem_src(j_decompress_ptr cinfo, unsigned char * inbuffer, unsigned long insize)
' Data source and destination managers: memory buffers.
Private Extern jpeg_mem_src(cinfo_ptr As Pointer, inbuffer As Byte[], insize As Long)

' int jpeg_read_header(j_decompress_ptr cinfo, boolean require_image)
' Read the JPEG datastream until the first SOS marker is encountered.
Private Extern jpeg_read_header(cinfo_ptr As Pointer, require_image As Boolean) As Integer

' boolean jpeg_start_decompress(j_decompress_ptr cinfo)
' Initialize state for a JPEG decompression cycle and allocate working memory.
Private Extern jpeg_start_decompress(cinfo_ptr As Pointer) As Boolean

' boolean jpeg_finish_decompress(j_decompress_ptr cinfo)
' Set the decompression state to completion.
Private Extern jpeg_finish_decompress(cinfo_ptr As Pointer) As Boolean

' void jpeg_destroy_decompress(j_decompress_ptr cinfo)
' Deallocate and release all memory associated with the decompression object.
Private Extern jpeg_destroy_decompress(cinfo_ptr As Pointer)


' unsigned char *  Legge_linee(struct jpeg_decompress_struct * cinfo, int bmp_size, int row_stride)
' Invoca la libreria externa appositamente creata per leggere le righe di pixel del file JPEG.
Private Extern Legge_linee(cinfo_ptr As Pointer, bmp_buf As Pointer, row As Integer) As Pointer In "/tmp/libadhoc"


Public Sub Main()

 Dim percorso, header As String
 Dim mgr, cinfo, bmp As Pointer
 Dim st As Stream
 Dim dim_jpg, dim_bmp As Long
 Dim fl As File
 Dim prog_riga, width, height As Integer
 Dim num_comp, dim_pixel, rc As Integer
 Dim buffer, buf, bb As Byte[]

' Crea la libreria esterna condivisa .so appositamente scritta:
 Creaso()
  
 percorso = "/percorso/del/file/immagine.jpg"
 If Not Exist(percorso) Then Error.Raise("Percorso file immagine inesistente !")
 Print "File immagine JPEG:  ", Null; percorso

' Carica i dati jpeg da un file in un buffer di memoria:
 dim_jpg = Stat(percorso).Size
 Print "Dimensione del file: "; dim_jpg; " byte"

 fl = Open percorso For Read

 With buffer = New Byte[dim_jpg]
   .Read(fl, 0, buffer.Max)
 End With

 fl.close()

 mgr = Alloc(Sizeof(gb.Byte), 168)
 cinfo = Alloc(Sizeof(gb.Byte), 656)
 
 st = Memory cinfo For Write
 Write #st, jpeg_std_error(mgr) As Pointer

 jpeg_CreateDecompress(cinfo, 80, 656)
 
 jpeg_mem_src(cinfo, buffer, dim_jpg)

 rc = jpeg_read_header(cinfo, True)
 If rc <> 1 Then Error.Raise("Il file non sembra essere un normale JPEG !")
 
' Comincia la decompressione dei dati JPEG:
 jpeg_start_decompress(cinfo)
 
 Seek #st, 48
 Read #st, width
 Print "Larghezza in pixel:  "; width
 Read #st, height
 Print "Altezza in pixel:    "; height
 Read #st, num_comp
 Read #st, dim_pixel
 Print "Byte per pixel:      "; num_comp; " (profondità: "; dim_pixel * 8; " bit)"
 st.Close
  
 dim_bmp = width * height * dim_pixel
 Print "Dimensione bitMap:   "; dim_bmp; " byte\n"
 
' La variabile "prog_riga" è il numero totale di byte che serve per memorizzare un'intera linea di scansione (riga):
 prog_riga = width * dim_pixel

' Al termine della decompressione, si va a leggere tutte le linee di scansione del jpeg, le quali di norma risultano disposte con l'ordine RGBRGBRGB (ordine che può essere cambiato agendo sul membro "cinfo.out_color_space"):
 bmp = Legge_linee(cinfo, dim_bmp, prog_riga)

 jpeg_finish_decompress(cinfo)  
 jpeg_destroy_decompress(cinfo)
' ''''''''''''''''''''''''''''''''''''''
  
' Ottenuti i dati grezzi, possiamo utilizzarli, ad esempio creando un file immagine non compresso (in questo caso di formato PNM):
 fl = Open "/tmp/file.ppm" For Create
 
 st = Memory bmp For Read
 bb = New Byte[dim_bmp]
 bb.Read(st)
 
 header = "P6 " & CStr(width) & " " & CStr(height) & " 255\n"
 
 With buf = Byte[].FromString(header)
   .Insert(bb)
   .Write(fl)
 End With

' Va in chiusura:
 st.Close
 fl.Close
 Free(cinfo)
 Free(mgr)

End

Private Procedure Creaso()
 
' Imposta il codice sorgente della parte in linguaggio C:
 File.Save("/tmp/libadhoc.c", "#include <stdio.h>\n#include <stdlib.h>\n#include <jpeglib.h>\n\n" &
           "unsigned char * bmp_buffer;\n\n" &
           "unsigned char *  Legge_linee(struct jpeg_decompress_struct * cinfo, int bmp_size, int row_stride) {\n\n" &
           "   bmp_buffer = (unsigned char*) malloc(bmp_size);\n\n" &
           "   while (cinfo->output_scanline < cinfo->output_height) {\n" &
           "     unsigned char *buffer_array[1];\n" &
           "     buffer_array[0] = bmp_buffer + (cinfo->output_scanline) * row_stride;\n" &
           "     jpeg_read_scanlines(cinfo, buffer_array, 1);\n   }\n\n" &
           "   return bmp_buffer;\n\n}")
 
' Crea la libreria esterna condivisa .so appositamente scritta per gestire la parte in linguaggio C:
 Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared -fPIC -ljpeg" Wait
 
End


Riferimenti