jw910731

GTK BMP viewer

Apr 15th, 2021
436
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×