Differenze tra le versioni di "Mostrare una immagine JPEG in una finestra con le funzioni del API di X11 e di Libjpeg"
(7 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
Per mostrare una immagine JPEG in una finestra creata con le risorse della libreria del server grafico ''X11'', sarà necessario decodificare il file immagine. | Per mostrare una immagine JPEG in una finestra creata con le risorse della libreria del server grafico ''X11'', sarà necessario decodificare il file immagine. | ||
− | <BR>Per effettuare tale decodifica ci serviremo delle risorse esterne della libreria ''Libjpeg''. | + | <BR>Per effettuare tale decodifica ci serviremo delle risorse esterne della libreria: "''Libjpeg'' ". |
Per maggiore sicurezza la maggior parte della procedura di decodifica sarà effettuata utilizzando istruzioni di codice in linguaggio C poste all'interno di una libreria condivisa .so, da noi realizzata, che sarà chiamata dal programma principale scritto in Gambas. | Per maggiore sicurezza la maggior parte della procedura di decodifica sarà effettuata utilizzando istruzioni di codice in linguaggio C poste all'interno di una libreria condivisa .so, da noi realizzata, che sarà chiamata dal programma principale scritto in Gambas. | ||
− | Per poter utilizzare le risorse esterne del API di ''X11'' sarà necessario richiamare la libreria | + | Per poter utilizzare le risorse esterne del API di ''X11'' sarà necessario richiamare la libreria condivisa: "''libX11.so.6.4.0'' ". |
− | |||
Pertanto, il codice C contenuto dalla libreria condivisa .so, da noi appositamente realizzata e che porremo nella cartella ''Dati'' dell'applicazione principale Gambas, supporta solo una profondità di colori non inferiore a 24 bit e sarà il seguente: | Pertanto, il codice C contenuto dalla libreria condivisa .so, da noi appositamente realizzata e che porremo nella cartella ''Dati'' dell'applicazione principale Gambas, supporta solo una profondità di colori non inferiore a 24 bit e sarà il seguente: | ||
Riga 20: | Riga 19: | ||
#ifndef u_char | #ifndef u_char | ||
#define u_char unsigned char | #define u_char unsigned char | ||
− | #endif | + | #endif |
− | + | <FONT Color=gray>''/*Ritorna un vettore per un'immagine a 24 bit.*/''</font> | |
− | <FONT Color=gray> | ||
u_char *Decodifica_jpeg (char *nomefile, int *widthP, int *heightP) { | u_char *Decodifica_jpeg (char *nomefile, int *widthP, int *heightP) { | ||
register JSAMPARRAY buffer; //--> occupa 8 byte | register JSAMPARRAY buffer; //--> occupa 8 byte | ||
Riga 109: | Riga 107: | ||
Il codice Gambas potrà essere il seguente: | Il codice Gambas potrà essere il seguente: | ||
+ | Private disp As Pointer | ||
+ | |||
+ | Library "libX11:6.4.0" | ||
+ | |||
Public Struct XEventStruct | Public Struct XEventStruct | ||
type As Integer | type As Integer | ||
Riga 136: | Riga 138: | ||
map_entries As Integer | map_entries As Integer | ||
End Struct | End Struct | ||
− | |||
Private Const ExposureMask As Integer = 32768 | Private Const ExposureMask As Integer = 32768 | ||
Private Const KeyPressMask As Byte = 1 | Private Const KeyPressMask As Byte = 1 | ||
Private Const ButtonPressMask As Byte = 4 | Private Const ButtonPressMask As Byte = 4 | ||
− | + | Private Const ZPixmap As Integer = 2 | |
Private Enum KeyPress = 2, KeyRelease, ButtonPress, ButtonRelease, MotionNotify, EnterNotify, | Private Enum KeyPress = 2, KeyRelease, ButtonPress, ButtonRelease, MotionNotify, EnterNotify, | ||
LeaveNotify, FocusIn, FocusOut, KeymapNotify, Expose, GraphicsExpose, NoExpose | LeaveNotify, FocusIn, FocusOut, KeymapNotify, Expose, GraphicsExpose, NoExpose | ||
− | + | <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)'' | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | <FONT Color=gray>' ''Display *XOpenDisplay( | ||
' ''Opens a connection to the X server that controls a display.''</font> | ' ''Opens a connection to the X server that controls a display.''</font> | ||
− | Private Extern XOpenDisplay(display$ As | + | Private Extern XOpenDisplay(display$ As Pointer) As Pointer |
− | <FONT Color=gray>' ''XCloseDisplay(display)'' | + | <FONT Color=gray>' ''XCloseDisplay(Display *display)'' |
' ''Closes the connection to the X server for the display specified in the Display structure and destroys all windows.''</font> | ' ''Closes the connection to the X server for the display specified in the Display structure and destroys all windows.''</font> | ||
Private Extern XCloseDisplay(displayP As Pointer) | Private Extern XCloseDisplay(displayP As Pointer) | ||
− | <FONT Color=gray>' ''int XDefaultScreen (display)'' | + | <FONT Color=gray>' ''int XDefaultScreen (Display *display)'' |
' ''returns the default screen number referenced by the XOpenDisplay function.''</font> | ' ''returns the default screen number referenced by the XOpenDisplay function.''</font> | ||
Private Extern XDefaultScreen(displayP As Pointer) As Integer | Private Extern XDefaultScreen(displayP As Pointer) As Integer | ||
− | <FONT Color=gray>' ''unsigned long XWhitePixel (display, screen_number)'' | + | <FONT Color=gray>' ''unsigned long XWhitePixel (Display *display, int screen_number)'' |
' ''returns the white pixel value for the specified screen.''</font> | ' ''returns the white pixel value for the specified screen.''</font> | ||
Private Extern XWhitePixel(displayP As Pointer, screen_number As Integer) As Long | Private Extern XWhitePixel(displayP As Pointer, screen_number As Integer) As Long | ||
− | <FONT Color=gray>' ''unsigned long XBlackPixel (display, screen_number)'' | + | <FONT Color=gray>' ''unsigned long XBlackPixel (Display *display, int screen_number)'' |
' ''returns the black pixel value for the specified screen.''</font> | ' ''returns the black pixel value for the specified screen.''</font> | ||
Private Extern XBlackPixel(displayP As Pointer, screen_number As Integer) As Long | Private Extern XBlackPixel(displayP As Pointer, screen_number As Integer) As Long | ||
− | <FONT Color=gray>' ''Window XDefaultRootWindow(display)'' | + | <FONT Color=gray>' ''Window XDefaultRootWindow(Display *display)'' |
' ''Return the root window for the default screen.''</font> | ' ''Return the root window for the default screen.''</font> | ||
Private Extern XDefaultRootWindow(displayP As Pointer) As Integer | Private Extern XDefaultRootWindow(displayP As Pointer) As Integer | ||
− | <FONT Color=gray>' ''Window XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background)'' | + | <FONT Color=gray>' ''Window XCreateSimpleWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, unsigned long border, unsigned long background)'' |
' ''Creates an unmapped InputOutput subwindow for a specified parent window, returns the window ID of the created window.''</font> | ' ''Creates an unmapped InputOutput subwindow for a specified parent window, returns the window ID of the created window.''</font> | ||
− | Private Extern XCreateSimpleWindow(displayP As Pointer, parent As | + | Private Extern XCreateSimpleWindow(displayP As Pointer, parent As Long, x As Integer, y As Integer, width As Integer, height As Integer, border_width As Integer, border As Integer, background As Long) As Integer |
− | <FONT Color=gray>' ''XSetStandardProperties (display, w, window_name, icon_name, icon_pixmap, argv, argc, hints)'' | + | <FONT Color=gray>' ''XSetStandardProperties (Display *display, Window w, char *window_name, char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints)'' |
' ''Specifies a minimum set of properties describing the simplest application.''</font> | ' ''Specifies a minimum set of properties describing the simplest application.''</font> | ||
− | Private Extern XSetStandardProperties(displayP As Pointer, w As | + | Private Extern XSetStandardProperties(displayP As Pointer, w As Long, window_name As String, icon_name As String, icon_pixmap As Integer, argv As String, argc As Integer, hints As Pointer) |
− | <FONT Color=gray>' ''XSelectInput (display, w, event_mask)'' | + | <FONT Color=gray>' ''XSelectInput (Display *display, Window w, long event_mask)'' |
' ''Requests that the X server report the events associated with the specified Event mask.''</font> | ' ''Requests that the X server report the events associated with the specified Event mask.''</font> | ||
− | Private Extern XSelectInput(displayP As Pointer, w As | + | Private Extern XSelectInput(displayP As Pointer, w As Long, event_mask As Long) |
− | <FONT Color=gray>' ''GC XCreateGC(display, d, valuemask, values)'' | + | <FONT Color=gray>' ''GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values)'' |
' ''Creates a graphics context and returns a GC.''</font> | ' ''Creates a graphics context and returns a GC.''</font> | ||
− | Private Extern XCreateGC(displayP As Pointer, w As | + | Private Extern XCreateGC(displayP As Pointer, w As Long, valuemask As Long, values As Pointer) As Pointer |
− | <FONT Color=gray>' ''XClearWindow(display, w)'' | + | <FONT Color=gray>' ''XClearWindow(Display *display, Window w)'' |
' ''Clears the entire area in the specified window.''</font> | ' ''Clears the entire area in the specified window.''</font> | ||
− | Private Extern XClearWindow(displayP As Pointer, w As | + | Private Extern XClearWindow(displayP As Pointer, w As Long) |
− | <FONT Color=gray>' ''XMapRaised (display, w)'' | + | <FONT Color=gray>' ''XMapRaised (Display *display, Window w)'' |
' ''Raises the specified window to the top of the stack.''</font> | ' ''Raises the specified window to the top of the stack.''</font> | ||
− | Private Extern XMapRaised(displayP As Pointer, w As | + | Private Extern XMapRaised(displayP As Pointer, w As Long) |
− | <FONT Color=gray>' ''XNextEvent (display, event_return)'' | + | <FONT Color=gray>' ''XNextEvent (Display *display, XEvent *event_return)'' |
' ''Gets the next event and remove it from the queue.''</font> | ' ''Gets the next event and remove it from the queue.''</font> | ||
Private Extern XNextEvent(displayP As Pointer, event_return As XEventStruct) | Private Extern XNextEvent(displayP As Pointer, event_return As XEventStruct) | ||
− | <FONT Color=gray>' ''XFreeGC(display, gc)'' | + | <FONT Color=gray>' ''XFreeGC(Display *display, GC gc)'' |
' Destroys the specified GC as well as all the associated storage.''</font> | ' Destroys the specified GC as well as all the associated storage.''</font> | ||
Private Extern XFreeGC(displayP As Pointer, gcP As Pointer) | Private Extern XFreeGC(displayP As Pointer, gcP As Pointer) | ||
− | <FONT Color=gray>' ''XDestroyWindow(display, w)'' | + | <FONT Color=gray>' ''XDestroyWindow(Display *display, Window w)'' |
' ''Destroys the specified window as well as all of its subwindows.''</font> | ' ''Destroys the specified window as well as all of its subwindows.''</font> | ||
− | Private Extern XDestroyWindow(displayP As Pointer, w As | + | Private Extern XDestroyWindow(displayP As Pointer, w As Long) |
− | <FONT Color=gray>' ''XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height)'' | + | <FONT Color=gray>' ''XPutImage(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)'' |
' ''Combines an image with a rectangle of the specified drawable.''</font> | ' ''Combines an image with a rectangle of the specified drawable.''</font> | ||
− | Private Extern XPutImage(displayP As Pointer, w As | + | Private Extern XPutImage(displayP As Pointer, w As Long, gcP As Pointer, image As Pointer, src_x As Integer, src_y As Integer, dest_x As Integer, dest_y As Integer, width As Integer, height As Integer) |
− | <FONT Color=gray>' ''int | + | <FONT Color=gray>' ''int XDefaultDepth(Display *display, int screen_number)'' |
' ''Returns the depth (number of planes) of the default root window for the specified screen.''</font> | ' ''Returns the depth (number of planes) of the default root window for the specified screen.''</font> | ||
Private Extern XDefaultDepth(displayP As Pointer, screen_number As Integer) As Integer | Private Extern XDefaultDepth(displayP As Pointer, screen_number As Integer) As Integer | ||
− | <FONT Color=gray>' ''Visual *XDefaultVisual(display, screen_number)'' | + | <FONT Color=gray>' ''Visual *XDefaultVisual(Display *display, int screen_number)'' |
' ''Returns the default visual type for the specified screen.''</font> | ' ''Returns the default visual type for the specified screen.''</font> | ||
Private Extern XDefaultVisual(displayP As Pointer, screen_number As Integer) As Visual | Private Extern XDefaultVisual(displayP As Pointer, screen_number As Integer) As Visual | ||
− | <FONT Color=gray>' ''XImage *XCreateImage(display, visual, depth, format, offset, data, width, height, bitmap_pad, bytes_per_line)'' | + | <FONT Color=gray>' ''XImage *XCreateImage(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line)'' |
' ''Allocates the memory needed for an XImage structure for the specified display but does not allocate space for the image itself.''</font> | ' ''Allocates the memory needed for an XImage structure for the specified display but does not allocate space for the image itself.''</font> | ||
Private Extern XCreateImage(displayP As Pointer, visu As Visual, depth As Integer, formatI As Integer, offset As Integer, data As Integer[], width As Integer, height As Integer, bitmap_pad As Integer, bytes_per_line As Integer) As Pointer | Private Extern XCreateImage(displayP As Pointer, visu As Visual, depth As Integer, formatI As Integer, offset As Integer, data As Integer[], width As Integer, height As Integer, bitmap_pad As Integer, bytes_per_line As Integer) As Pointer | ||
− | <FONT Color=gray>' ''Status XInitImage(image)'' | + | <FONT Color=gray>' ''Status XInitImage(XImage *image)'' |
' ''Initializes the internal image manipulation routines of an image structure, based on the values of the various structure members.''</font> | ' ''Initializes the internal image manipulation routines of an image structure, based on the values of the various structure members.''</font> | ||
Private Extern XInitImage(image As Pointer) | Private Extern XInitImage(image As Pointer) | ||
+ | <FONT Color=gray>' ''void exit(int status)'' | ||
+ | ' ''Terminates the calling process immediately.Any Open file descriptors belonging To the process are closed And any children Of the process are inherited.''</font> | ||
Private Extern exitus(status As Integer) In "libc:6" Exec "exit" | Private Extern exitus(status As Integer) In "libc:6" Exec "exit" | ||
− | |||
Private Extern Decodifica_jpeg(FileImmagine As String, wP As Pointer, hP As Pointer) As Pointer In "/tmp/libadhoc_jpeg" | Private Extern Decodifica_jpeg(FileImmagine As String, wP As Pointer, hP As Pointer) As Pointer In "/tmp/libadhoc_jpeg" | ||
Riga 241: | Riga 236: | ||
'''Public''' Sub Main() | '''Public''' Sub Main() | ||
− | Dim screen | + | Dim screen, prof, iW, iH As Integer |
− | Dim pxW, pxB As Long | + | Dim pxW, pxB, id As Long |
Dim ev As New XEventStruct | Dim ev As New XEventStruct | ||
− | Dim | + | Dim p, img, gc As Pointer |
Dim ImmBuffer As Integer[] | Dim ImmBuffer As Integer[] | ||
<FONT Color=gray>' ''Crea la nostra libreria condivisa ad hoc:''</font> | <FONT Color=gray>' ''Crea la nostra libreria condivisa ad hoc:''</font> | ||
− | + | If Exist("/tmp/libadhoc_jpeg.c") = False Then Copy "libadhoc_jpeg.c" To "/tmp/libadhoc_jpeg.c" | |
− | + | Shell "gcc -o /tmp/libadhoc_jpeg.so /tmp/libadhoc_jpeg.c -shared -fPIC -lX11 -ljpeg" Wait | |
+ | |||
+ | p = Decodifica_jpeg("<FONT Color=gray>''/percorso/del/file/immagine.jpg''</font>", VarPtr(iW), VarPtr(iH)) | ||
+ | If p == 0 Then Error.Raise("Errore !") | ||
− | + | disp = XOpenDisplay(0) | |
− | + | If disp == 0 Then Error.Raise("Impossibile aprire il display !") | |
− | |||
− | |||
− | + | screen = XDefaultScreen(disp) | |
− | + | prof = XDefaultDepth(disp, screen) | |
− | + | ImmBuffer = Crea_Dati_immagine(screen, prof, p, iW, iH) | |
− | + | img = XCreateImage(disp, Null, prof, ZPixmap, 0, ImmBuffer, iW, iH, 32, 0) | |
− | + | If img == 0 Then Error.Raise("Errore !") | |
− | + | pxW = XWhitePixel(disp, screen) | |
− | + | pxB = XBlackPixel(disp, screen) | |
− | |||
− | + | id = XCreateSimpleWindow(disp, XDefaultRootWindow(disp), 0, 0, iW, iH, 5, pxW, &FF0000) | |
− | + | Print "ID della finestra creata: "; Hex(id, 6) | |
− | |||
− | |||
− | + | XSetStandardProperties(disp, id, "Prova creazione finestra", "Nome icona finestra", 0, Null, 0, Null) | |
+ | XSelectInput(disp, id, ExposureMask Or KeyPressMask Or ButtonPressMask) | ||
− | + | gc = XCreateGC(disp, id, 0, Null) | |
− | + | If gc == 0 Then Error.Raise("Impossibile creare un nuovo contesto grafico !") | |
− | + | XMapRaised(disp, id) | |
− | + | While True | |
− | + | XNextEvent(disp, ev) | |
− | + | Select Case ev.type | |
− | + | Case Expose | |
− | + | redraw(id) | |
− | + | XInitImage(img) | |
− | + | XPutImage(disp, id, gc, img, 0, 0, 0, 0, iW, IH) | |
− | + | Case Else | |
− | + | Exit | |
− | + | End Select | |
− | + | Wend | |
− | |||
− | |||
− | |||
− | |||
− | + | chiude_X(id, gc) | |
'''End''' | '''End''' | ||
− | |||
'''Private''' Procedure redraw(idR As Integer) | '''Private''' Procedure redraw(idR As Integer) | ||
<FONT Color=gray>' ''Pulisce la superficie della finestra da ogni elemento presente:''</font> | <FONT Color=gray>' ''Pulisce la superficie della finestra da ogni elemento presente:''</font> | ||
− | + | XClearWindow(disp, idR) | |
'''End''' | '''End''' | ||
+ | '''Private''' Procedure chiude_X(idCh As Integer, gcont As Pointer) | ||
− | + | XFreeGC(disp, gcont) | |
− | |||
− | |||
− | |||
<FONT Color=gray>' ''Chiude la finestra:''</font> | <FONT Color=gray>' ''Chiude la finestra:''</font> | ||
− | + | XDestroyWindow(disp, idCh) | |
− | + | XCloseDisplay(disp) | |
− | + | exitus(0) | |
− | |||
− | |||
'''End''' | '''End''' | ||
− | |||
'''Private''' Function Crea_Dati_immagine(screen As Integer, profond As Integer, buf As Pointer, width As Integer, height As Integer) As Integer[] | '''Private''' Function Crea_Dati_immagine(screen As Integer, profond As Integer, buf As Pointer, width As Integer, height As Integer) As Integer[] | ||
Riga 332: | Riga 316: | ||
Dim buffer As Byte | Dim buffer As Byte | ||
− | + | vis = XDefaultVisual(disp, screen) | |
− | |||
− | + | rRatio = CFloat(vis.red_mask) / 255.0 | |
− | + | gRatio = CFloat(vis.green_mask) / 255.0 | |
− | + | bRatio = CFloat(vis.blue_mask) / 255.0 | |
− | + | st = Memory buf For Read | |
− | + | If profond >= 24 Then | |
− | + | vettI = New Integer[](width * height) | |
− | + | Repeat | |
− | + | Read #st, buffer | |
+ | r = CInt(buffer * rRatio) | ||
+ | |||
+ | Read #st, buffer | ||
+ | g = CInt(buffer * gRatio) | ||
− | + | Read #st, buffer | |
− | + | b = CInt(buffer * bRatio) | |
− | + | r = r And vis.red_mask | |
− | + | g = g And vis.green_mask | |
+ | b = b And vis.blue_mask | ||
− | + | vettI[scorr] = r Or g Or b | |
− | + | Inc scorr | |
+ | Until scorr >= vettI.Max | ||
+ | Else | ||
+ | Error.Raise("Questa applicazione non supporta una profondità inferiore a 24 !") | ||
+ | Endif | ||
− | + | st.Close | |
− | |||
− | |||
− | + | Return vettI | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
'''End''' | '''End''' | ||
− | |||
Versione attuale delle 15:54, 1 mag 2023
Per mostrare una immagine JPEG in una finestra creata con le risorse della libreria del server grafico X11, sarà necessario decodificare il file immagine.
Per effettuare tale decodifica ci serviremo delle risorse esterne della libreria: "Libjpeg ".
Per maggiore sicurezza la maggior parte della procedura di decodifica sarà effettuata utilizzando istruzioni di codice in linguaggio C poste all'interno di una libreria condivisa .so, da noi realizzata, che sarà chiamata dal programma principale scritto in Gambas.
Per poter utilizzare le risorse esterne del API di X11 sarà necessario richiamare la libreria condivisa: "libX11.so.6.4.0 ".
Pertanto, il codice C contenuto dalla libreria condivisa .so, da noi appositamente realizzata e che porremo nella cartella Dati dell'applicazione principale Gambas, supporta solo una profondità di colori non inferiore a 24 bit e sarà il seguente:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <X11/Xlib.h> #include <X11/keysym.h> #include <jpeglib.h> #include <jerror.h> #ifndef u_char #define u_char unsigned char #endif /*Ritorna un vettore per un'immagine a 24 bit.*/ u_char *Decodifica_jpeg (char *nomefile, int *widthP, int *heightP) { register JSAMPARRAY buffer; //--> occupa 8 byte struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr err_mgr; int bytePerPixel, x, y; FILE *fl; u_char *BufferRitorno; fl = fopen (nomefile, "rb"); if (NULL == fl) { perror (NULL); return NULL; } cinfo.err = jpeg_std_error (&err_mgr); jpeg_create_decompress (&cinfo); jpeg_stdio_src (&cinfo, fl); jpeg_read_header (&cinfo, 1); cinfo.do_fancy_upsampling = 0; cinfo.do_block_smoothing = 0; jpeg_start_decompress (&cinfo); *widthP = cinfo.output_width; *heightP = cinfo.output_height; bytePerPixel = cinfo.output_components; buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, (*widthP * bytePerPixel), 1); BufferRitorno = malloc (3 * (*widthP * *heightP)); if (NULL == BufferRitorno) { perror (NULL); return NULL; } if (3 == bytePerPixel) { int scorrLinea = (*widthP * 3); for (y = 0; y < cinfo.output_height; ++y) { jpeg_read_scanlines (&cinfo, buffer, 1); for (x = 0; x < scorrLinea; ++x) { BufferRitorno[(scorrLinea * y) + x] = buffer[0][x]; ++x; BufferRitorno[(scorrLinea * y) + x] = buffer[0][x]; ++x; BufferRitorno[(scorrLinea * y) + x] = buffer[0][x]; } } } else if (1 == bytePerPixel) { unsigned int col; int scorrLinea = (*widthP * 3); int indiceBuff; for (y = 0; y < cinfo.output_height; ++y) { jpeg_read_scanlines (&cinfo, buffer, 1); indiceBuff = 0; for (x = 0; x < scorrLinea; ++x) { col = buffer[0][indiceBuff]; BufferRitorno[(scorrLinea * y) + x] = col; ++x; BufferRitorno[(scorrLinea * y) + x] = col; ++x; BufferRitorno[(scorrLinea * y) + x] = col; ++indiceBuff; } } } else { fprintf (stderr, "Errore: il numero dei canali del colore è %d. Questa applicazione può gestire soltanto 1 o 3\n", bytePerPixel); return NULL; } jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); fclose (fl); return BufferRitorno; }
Il codice Gambas potrà essere il seguente:
Private disp As Pointer Library "libX11:6.4.0" Public Struct XEventStruct type As Integer serial As Long send_event As Boolean display As Pointer windowL As Long root As Long subwindow As Long timeL As Long x As Integer y As Integer x_root As Integer y_root As Integer state As Integer keycode As Integer same_screen As Boolean End Struct Public Struct Visual XExtData As Pointer visualid As Integer classe As Long red_mask As Long green_mask As Long blue_mask As Long map_entries As Integer End Struct Private Const ExposureMask As Integer = 32768 Private Const KeyPressMask As Byte = 1 Private Const ButtonPressMask As Byte = 4 Private Const ZPixmap As Integer = 2 Private Enum KeyPress = 2, KeyRelease, ButtonPress, ButtonRelease, MotionNotify, EnterNotify, LeaveNotify, FocusIn, FocusOut, KeymapNotify, Expose, GraphicsExpose, NoExpose ' Display *XOpenDisplay(char *display_name) ' Opens a connection to the X server that controls a display. Private Extern XOpenDisplay(display$ As Pointer) As Pointer ' XCloseDisplay(Display *display) ' Closes the connection to the X server for the display specified in the Display structure and destroys all windows. Private Extern XCloseDisplay(displayP As Pointer) ' int XDefaultScreen (Display *display) ' returns the default screen number referenced by the XOpenDisplay function. Private Extern XDefaultScreen(displayP As Pointer) As Integer ' unsigned long XWhitePixel (Display *display, int screen_number) ' returns the white pixel value for the specified screen. Private Extern XWhitePixel(displayP As Pointer, screen_number As Integer) As Long ' unsigned long XBlackPixel (Display *display, int screen_number) ' returns the black pixel value for the specified screen. Private Extern XBlackPixel(displayP As Pointer, screen_number As Integer) As Long ' Window XDefaultRootWindow(Display *display) ' Return the root window for the default screen. Private Extern XDefaultRootWindow(displayP As Pointer) As Integer ' Window XCreateSimpleWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, unsigned long border, unsigned long background) ' Creates an unmapped InputOutput subwindow for a specified parent window, returns the window ID of the created window. Private Extern XCreateSimpleWindow(displayP As Pointer, parent As Long, x As Integer, y As Integer, width As Integer, height As Integer, border_width As Integer, border As Integer, background As Long) As Integer ' XSetStandardProperties (Display *display, Window w, char *window_name, char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints) ' Specifies a minimum set of properties describing the simplest application. Private Extern XSetStandardProperties(displayP As Pointer, w As Long, window_name As String, icon_name As String, icon_pixmap As Integer, argv As String, argc As Integer, hints As Pointer) ' XSelectInput (Display *display, Window w, long event_mask) ' Requests that the X server report the events associated with the specified Event mask. Private Extern XSelectInput(displayP As Pointer, w As Long, event_mask As Long) ' GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values) ' Creates a graphics context and returns a GC. Private Extern XCreateGC(displayP As Pointer, w As Long, valuemask As Long, values As Pointer) As Pointer ' XClearWindow(Display *display, Window w) ' Clears the entire area in the specified window. Private Extern XClearWindow(displayP As Pointer, w As Long) ' XMapRaised (Display *display, Window w) ' Raises the specified window to the top of the stack. Private Extern XMapRaised(displayP As Pointer, w As Long) ' XNextEvent (Display *display, XEvent *event_return) ' Gets the next event and remove it from the queue. Private Extern XNextEvent(displayP As Pointer, event_return As XEventStruct) ' XFreeGC(Display *display, GC gc) ' Destroys the specified GC as well as all the associated storage. Private Extern XFreeGC(displayP As Pointer, gcP As Pointer) ' XDestroyWindow(Display *display, Window w) ' Destroys the specified window as well as all of its subwindows. Private Extern XDestroyWindow(displayP As Pointer, w As Long) ' XPutImage(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height) ' Combines an image with a rectangle of the specified drawable. Private Extern XPutImage(displayP As Pointer, w As Long, gcP As Pointer, image As Pointer, src_x As Integer, src_y As Integer, dest_x As Integer, dest_y As Integer, width As Integer, height As Integer) ' int XDefaultDepth(Display *display, int screen_number) ' Returns the depth (number of planes) of the default root window for the specified screen. Private Extern XDefaultDepth(displayP As Pointer, screen_number As Integer) As Integer ' Visual *XDefaultVisual(Display *display, int screen_number) ' Returns the default visual type for the specified screen. Private Extern XDefaultVisual(displayP As Pointer, screen_number As Integer) As Visual ' XImage *XCreateImage(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line) ' Allocates the memory needed for an XImage structure for the specified display but does not allocate space for the image itself. Private Extern XCreateImage(displayP As Pointer, visu As Visual, depth As Integer, formatI As Integer, offset As Integer, data As Integer[], width As Integer, height As Integer, bitmap_pad As Integer, bytes_per_line As Integer) As Pointer ' Status XInitImage(XImage *image) ' Initializes the internal image manipulation routines of an image structure, based on the values of the various structure members. Private Extern XInitImage(image As Pointer) ' void exit(int status) ' Terminates the calling process immediately.Any Open file descriptors belonging To the process are closed And any children Of the process are inherited. Private Extern exitus(status As Integer) In "libc:6" Exec "exit" Private Extern Decodifica_jpeg(FileImmagine As String, wP As Pointer, hP As Pointer) As Pointer In "/tmp/libadhoc_jpeg" Public Sub Main() Dim screen, prof, iW, iH As Integer Dim pxW, pxB, id As Long Dim ev As New XEventStruct Dim p, img, gc As Pointer Dim ImmBuffer As Integer[] ' Crea la nostra libreria condivisa ad hoc: If Exist("/tmp/libadhoc_jpeg.c") = False Then Copy "libadhoc_jpeg.c" To "/tmp/libadhoc_jpeg.c" Shell "gcc -o /tmp/libadhoc_jpeg.so /tmp/libadhoc_jpeg.c -shared -fPIC -lX11 -ljpeg" Wait p = Decodifica_jpeg("/percorso/del/file/immagine.jpg", VarPtr(iW), VarPtr(iH)) If p == 0 Then Error.Raise("Errore !") disp = XOpenDisplay(0) If disp == 0 Then Error.Raise("Impossibile aprire il display !") screen = XDefaultScreen(disp) prof = XDefaultDepth(disp, screen) ImmBuffer = Crea_Dati_immagine(screen, prof, p, iW, iH) img = XCreateImage(disp, Null, prof, ZPixmap, 0, ImmBuffer, iW, iH, 32, 0) If img == 0 Then Error.Raise("Errore !") pxW = XWhitePixel(disp, screen) pxB = XBlackPixel(disp, screen) id = XCreateSimpleWindow(disp, XDefaultRootWindow(disp), 0, 0, iW, iH, 5, pxW, &FF0000) Print "ID della finestra creata: "; Hex(id, 6) XSetStandardProperties(disp, id, "Prova creazione finestra", "Nome icona finestra", 0, Null, 0, Null) XSelectInput(disp, id, ExposureMask Or KeyPressMask Or ButtonPressMask) gc = XCreateGC(disp, id, 0, Null) If gc == 0 Then Error.Raise("Impossibile creare un nuovo contesto grafico !") XMapRaised(disp, id) While True XNextEvent(disp, ev) Select Case ev.type Case Expose redraw(id) XInitImage(img) XPutImage(disp, id, gc, img, 0, 0, 0, 0, iW, IH) Case Else Exit End Select Wend chiude_X(id, gc) End Private Procedure redraw(idR As Integer) ' Pulisce la superficie della finestra da ogni elemento presente: XClearWindow(disp, idR) End Private Procedure chiude_X(idCh As Integer, gcont As Pointer) XFreeGC(disp, gcont) ' Chiude la finestra: XDestroyWindow(disp, idCh) XCloseDisplay(disp) exitus(0) End Private Function Crea_Dati_immagine(screen As Integer, profond As Integer, buf As Pointer, width As Integer, height As Integer) As Integer[] Dim r, g, b, scorr As Integer Dim vis As New Visual Dim rRatio, gRatio, bRatio As Float Dim vettI As Integer[] Dim st As Stream Dim buffer As Byte vis = XDefaultVisual(disp, screen) rRatio = CFloat(vis.red_mask) / 255.0 gRatio = CFloat(vis.green_mask) / 255.0 bRatio = CFloat(vis.blue_mask) / 255.0 st = Memory buf For Read If profond >= 24 Then vettI = New Integer[](width * height) Repeat Read #st, buffer r = CInt(buffer * rRatio) Read #st, buffer g = CInt(buffer * gRatio) Read #st, buffer b = CInt(buffer * bRatio) r = r And vis.red_mask g = g And vis.green_mask b = b And vis.blue_mask vettI[scorr] = r Or g Or b Inc scorr Until scorr >= vettI.Max Else Error.Raise("Questa applicazione non supporta una profondità inferiore a 24 !") Endif st.Close Return vettI End