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%. ...')
 
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 dinamica condivisa: "''libjpeg.so.8.0.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:
 
#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"
 
  Library "libjpeg:8.0.2"
 
   
 
   
Riga 68: Riga 37:
 
   
 
   
 
   
 
   
 +
<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 49:
 
   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 = "''/percorso/del/file/immagine.jpg''"
 
   percorso = "''/percorso/del/file/immagine.jpg''"
 +
  If Not Exist(percorso) Then Error.Raise("Percorso file immagine inesistente !")
 
   Print "File immagine JPEG: ", Null; percorso
 
   Print "File immagine JPEG: ", Null; percorso
 
   
 
   
Riga 100: Riga 71:
 
   
 
   
 
   fl.close()
 
   fl.close()
 
 
   
 
   
 
   mgr = Alloc(168)
 
   mgr = Alloc(168)
Riga 120: Riga 90:
 
   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: ", Null; dim_bmp; " byte\n"
Riga 141: Riga 111:
 
      
 
      
 
   jpeg_destroy_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>
Riga 164: Riga 134:
 
   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 delle 09:16, 8 mar 2018

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 dinamica condivisa: "libjpeg.so.8.0.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.0.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: ", Null; 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(168)
  cinfo = Alloc(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: ", Null; 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