image_hash_matcher.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include "image_hash_matcher.h"
  2. /**
  3. * vips_image_read_to_memory: converts VipsImage to RGBA format and reads into memory buffer
  4. * @in: VipsImage to convert and read
  5. * @buf: pointer to buffer pointer (will be allocated)
  6. * @size: pointer to size_t to store the buffer size
  7. *
  8. * Converts the VipsImage to RGBA format using VIPS operations and reads the raw pixel data.
  9. * The caller is responsible for freeing the buffer using vips_memory_buffer_free().
  10. *
  11. * Returns: 0 on success, -1 on error
  12. */
  13. int
  14. vips_image_read_from_to_memory(void *in, size_t in_size, void **out, size_t *out_size, int *out_width, int *out_height)
  15. {
  16. if (!in || !out || !out_size || !out_width || !out_height) {
  17. vips_error("vips_image_read_from_to_memory", "invalid arguments");
  18. return -1;
  19. }
  20. VipsImage *base = vips_image_new_from_buffer(in, in_size, "", NULL);
  21. if (base == NULL) {
  22. return -1;
  23. }
  24. // NOTE: Looks like there is a vips bug: if there were errors during format detection,
  25. // they would be saved in vips error buffer. However, if format detection was successful,
  26. // we expect that error buffer should be empty.
  27. // vips_error_clear();
  28. VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 2);
  29. // Initialize output parameters
  30. *out = NULL;
  31. *out_size = 0;
  32. // Convert to sRGB colorspace first if needed
  33. if (vips_colourspace(base, &t[0], VIPS_INTERPRETATION_sRGB, NULL) != 0) {
  34. VIPS_UNREF(base);
  35. vips_error("vips_image_read_from_to_memory", "failed to convert to sRGB");
  36. return -1;
  37. }
  38. in = t[0];
  39. // Add alpha channel if not present (convert to RGBA)
  40. if (!vips_image_hasalpha(base)) {
  41. // Add alpha channel
  42. if (vips_addalpha(base, &t[1], NULL) != 0) {
  43. VIPS_UNREF(base);
  44. vips_error("vips_image_read_from_to_memory", "failed to add alpha channel");
  45. return -1;
  46. }
  47. in = t[1];
  48. }
  49. // Get raw pixel data, width and height
  50. *out = vips_image_write_to_memory(in, out_size);
  51. *out_width = base->Xsize;
  52. *out_height = base->Ysize;
  53. // Dispose the image regardless of the result
  54. VIPS_UNREF(base);
  55. if (*out == NULL) {
  56. vips_error("vips_image_read_from_to_memory", "failed to write image to memory");
  57. return -1;
  58. }
  59. return 0;
  60. }
  61. /**
  62. * vips_memory_buffer_free: frees memory buffer allocated by vips_image_write_to_memory
  63. * @buf: buffer pointer to free
  64. *
  65. * Frees the memory buffer allocated by vips_image_write_to_memory.
  66. * Safe to call with NULL pointer.
  67. */
  68. void
  69. vips_memory_buffer_free(void *buf)
  70. {
  71. if (buf) {
  72. g_free(buf);
  73. }
  74. }