Formerly some fooling around with RISC-V, then mostly fooling around with virtio, finally mostly the original repo of RISK-V. The only difference is the S-o-bs and author/committer names. Suffice to say this is still the original.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

image.c 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include <assert.h>
  2. #include <errno.h>
  3. #include <nonstddef.h>
  4. #include <png.h>
  5. #include <stdbool.h>
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. static const char *current_png;
  12. static bool png_had_error;
  13. static void png_error_func(png_struct *png, const char *msg)
  14. {
  15. (void)png;
  16. png_had_error = true;
  17. printf("[image] %s: %s\n", current_png, msg);
  18. }
  19. bool load_image(const char *name, uint32_t **dest, int *w, int *h, int stride)
  20. {
  21. FILE *fp = NULL;
  22. png_struct *png = NULL;
  23. png_info *info = NULL;
  24. uint32_t png_w, png_h;
  25. bool ret = false;
  26. if (stride || *dest) {
  27. assert(*w && *h);
  28. }
  29. fp = fopen(name, "rb");
  30. if (!fp) {
  31. printf("[image] %s: %s\n", name, strerror(errno));
  32. goto fail;
  33. }
  34. png_had_error = false;
  35. current_png = name;
  36. png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
  37. png_error_func, NULL);
  38. assert(png);
  39. info = png_create_info_struct(png);
  40. assert(info);
  41. png_init_io(png, fp);
  42. png_read_info(png, info);
  43. png_get_IHDR(png, info, &png_w, &png_h, NULL, NULL, NULL, NULL, NULL);
  44. if ((*w && (int)png_w != *w) || (*h && (int)png_h != *h)) {
  45. printf("[image] %s: Wrong dimensions (expected %ix%i, got %ix%i)\n",
  46. name, *w, *h, (int)png_w, (int)png_h);
  47. goto fail;
  48. }
  49. *w = png_w;
  50. *h = png_h;
  51. stride = MAX(stride, (int)(png_w * sizeof(uint32_t)));
  52. png_set_scale_16(png);
  53. png_set_packing(png);
  54. png_set_palette_to_rgb(png);
  55. png_set_expand_gray_1_2_4_to_8(png);
  56. png_set_tRNS_to_alpha(png);
  57. png_set_bgr(png);
  58. png_set_filler(png, 0, PNG_FILLER_AFTER);
  59. png_read_update_info(png, info);
  60. if (!*dest) {
  61. *dest = malloc(png_h * stride);
  62. }
  63. {
  64. unsigned char *rows[png_h];
  65. for (int i = 0; i < (int)png_h; i++) {
  66. rows[i] = (unsigned char *)*dest + i * stride;
  67. }
  68. png_read_image(png, rows);
  69. }
  70. png_read_end(png, info);
  71. if (png_had_error) {
  72. goto fail;
  73. }
  74. ret = true;
  75. fail:
  76. png_destroy_read_struct(&png, &info, NULL);
  77. if (fp) {
  78. fclose(fp);
  79. }
  80. return ret;
  81. }