Advertisement
jw910731

GTK BMP viewer

Apr 15th, 2021
695
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.20 KB | None | 0 0
  1. //#include <config.h>
  2. #include <glib/gi18n.h>
  3. #include <gtk/gtk.h>
  4. #include <stdint.h>
  5.  
  6. struct _sBmpHeader {
  7.     char bm[2];
  8.     uint32_t size;
  9.     uint32_t reserve;
  10.     uint32_t offset;
  11.     uint32_t header_size;
  12.     uint32_t width;
  13.     uint32_t height;
  14.     uint16_t planes;
  15.     uint16_t bpp;
  16.     uint32_t compression;
  17.     uint32_t bitmap_size;
  18.     uint32_t hres;
  19.     uint32_t vres;
  20.     uint32_t used;
  21.     uint32_t important;
  22. } __attribute__((__packed__));
  23.  
  24. typedef struct _sBmpHeader sBmpHeader;
  25.  
  26. static void on_open_image(GtkButton *button, gpointer user_data) {
  27.     GtkWidget *image = GTK_WIDGET(user_data);
  28.     GtkWidget *toplevel = gtk_widget_get_toplevel(image);
  29.     GtkFileFilter *filter = gtk_file_filter_new();
  30.     GtkWidget *dialog = gtk_file_chooser_dialog_new(
  31.         _("Open image"), GTK_WINDOW(toplevel), GTK_FILE_CHOOSER_ACTION_OPEN,
  32.         GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL,
  33.         GTK_RESPONSE_CANCEL, NULL);
  34.  
  35.     gtk_file_filter_add_pixbuf_formats(filter);
  36.     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
  37.  
  38.     switch (gtk_dialog_run(GTK_DIALOG(dialog))) {
  39.         case GTK_RESPONSE_ACCEPT: {
  40.             gchar *filename =
  41.                 gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
  42.             // gtk_image_set_from_file (GTK_IMAGE (image), filename);
  43.  
  44.             /*
  45.             GdkPixbuf *
  46. gdk_pixbuf_new (GdkColorspace colorspace,
  47.     gboolean has_alpha,
  48.     int bits_per_sample,
  49.     int width,
  50.     int height);
  51. */
  52.  
  53.             FILE *pFile = NULL;
  54.  
  55.             if ((pFile = fopen(filename, "rb")) == NULL) {
  56.                 printf("File could not be opened!\n");
  57.                 return;
  58.             }
  59.  
  60.             sBmpHeader header;
  61.             fread(&header, 54, 1, pFile);
  62.  
  63.             GdkPixbuf *pBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 0, 8,
  64.                                              header.width, header.height);
  65.  
  66.             guchar *pixels = gdk_pixbuf_get_pixels(pBuf);
  67.  
  68.             size_t offset = 0;
  69.  
  70.             uint8_t *row_buf = malloc(header.width * sizeof(uint8_t) * 3);
  71.  
  72.             while (!feof(pFile)) {
  73.                 size_t count = fread(row_buf, 1,
  74.                                      header.width * sizeof(uint8_t) * 3, pFile);
  75.  
  76.                 // bgr -> rgb
  77.                 for (uint8_t *it = row_buf; it - row_buf < header.width * 3;
  78.                      it += 3) {
  79.                     // swap
  80.                     uint8_t tmp = it[0];
  81.                     it[0] = it[2];
  82.                     it[2] = tmp;
  83.                 }
  84.  
  85.                 memcpy(pixels +
  86.                            ((header.width * 3 * (header.height - 1)) - offset),
  87.                        row_buf, count);
  88.  
  89.                 offset += count;
  90.             }
  91.  
  92.             free(row_buf);
  93.  
  94.             gtk_image_set_from_pixbuf(GTK_IMAGE(image), pBuf);
  95.  
  96.             break;
  97.         }
  98.         default:
  99.             break;
  100.     }
  101.     gtk_widget_destroy(dialog);
  102. }
  103.  
  104. static GtkWidget *create_window(void) {
  105.     GtkWidget *window;
  106.     GtkWidget *button;
  107.     GtkWidget *image;
  108.     GtkWidget *box;
  109.  
  110.     /* Set up the UI */
  111.     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  112.     gtk_window_set_title(GTK_WINDOW(window), "image-viewer-c");
  113.  
  114.     box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
  115.     button = gtk_button_new_with_label(_("Open image"));
  116.     image = gtk_image_new();
  117.  
  118.     gtk_box_pack_start(GTK_BOX(box), image, TRUE, TRUE, 0);
  119.     gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
  120.  
  121.     gtk_container_add(GTK_CONTAINER(window), box);
  122.  
  123.     /* Connect signals */
  124.  
  125.     /* Show open dialog when opening a file */
  126.     g_signal_connect(button, "clicked", G_CALLBACK(on_open_image), image);
  127.  
  128.     /* Exit when the window is closed */
  129.     g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  130.  
  131.     return window;
  132. }
  133.  
  134. int main(int argc, char *argv[]) {
  135.     GtkWidget *window;
  136.  
  137. #ifdef ENABLE_NLS
  138.     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
  139.     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
  140.     textdomain(GETTEXT_PACKAGE);
  141. #endif
  142.  
  143.     gtk_init(&argc, &argv);
  144.  
  145.     window = create_window();
  146.     gtk_widget_show_all(window);
  147.  
  148.     gtk_main();
  149.     return 0;
  150. }
  151.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement