ImageDecoder.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/HashMap.h>
  9. #include <AK/OwnPtr.h>
  10. #include <AK/RefCounted.h>
  11. #include <AK/RefPtr.h>
  12. #include <AK/String.h>
  13. #include <LibGfx/Bitmap.h>
  14. #include <LibGfx/CMYKBitmap.h>
  15. #include <LibGfx/Size.h>
  16. #include <LibGfx/VectorGraphic.h>
  17. namespace Gfx {
  18. class Bitmap;
  19. struct ImageFrameDescriptor {
  20. RefPtr<Bitmap> image;
  21. int duration { 0 };
  22. };
  23. struct VectorImageFrameDescriptor {
  24. RefPtr<VectorGraphic> image;
  25. int duration { 0 };
  26. };
  27. class Metadata {
  28. public:
  29. Metadata() = default;
  30. virtual ~Metadata() = default;
  31. HashMap<StringView, String> const& main_tags() const
  32. {
  33. if (m_main_tags.is_empty())
  34. fill_main_tags();
  35. // This is designed to be used in a general GUI, don't include too much information here.
  36. VERIFY(m_main_tags.size() < 8);
  37. return m_main_tags;
  38. }
  39. protected:
  40. virtual void fill_main_tags() const {};
  41. mutable HashMap<StringView, String> m_main_tags;
  42. };
  43. enum class NaturalFrameFormat {
  44. RGB,
  45. Grayscale,
  46. CMYK,
  47. Vector,
  48. };
  49. class ImageDecoderPlugin {
  50. public:
  51. virtual ~ImageDecoderPlugin() = default;
  52. // Each plugin should implement these static functions and register them in ImageDecoder.cpp
  53. // Implement sniff() if the file includes a magic number
  54. // static bool sniff(ReadonlyBytes);
  55. // Implement validate_before_create() otherwise
  56. // static ErrorOr<bool> validate_before_create(ReadonlyBytes);
  57. // This function should be used to both create the context and parse the image header.
  58. // static ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> create(ReadonlyBytes);
  59. // This should always be available as gathered in create()
  60. virtual IntSize size() = 0;
  61. // Override this if the format supports animated images
  62. virtual bool is_animated() { return false; }
  63. virtual size_t loop_count() { return 0; }
  64. virtual size_t frame_count() { return 1; }
  65. virtual size_t first_animated_frame_index() { return 0; }
  66. virtual ErrorOr<ImageFrameDescriptor> frame(size_t index, Optional<IntSize> ideal_size = {}) = 0;
  67. virtual Optional<Metadata const&> metadata() { return OptionalNone {}; }
  68. virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() { return OptionalNone {}; }
  69. virtual NaturalFrameFormat natural_frame_format() const { return NaturalFrameFormat::RGB; }
  70. virtual ErrorOr<NonnullRefPtr<CMYKBitmap>> cmyk_frame() { VERIFY_NOT_REACHED(); }
  71. virtual ErrorOr<VectorImageFrameDescriptor> vector_frame(size_t) { VERIFY_NOT_REACHED(); }
  72. protected:
  73. ImageDecoderPlugin() = default;
  74. };
  75. class ImageDecoder : public RefCounted<ImageDecoder> {
  76. public:
  77. static ErrorOr<RefPtr<ImageDecoder>> try_create_for_raw_bytes(ReadonlyBytes, Optional<ByteString> mime_type = {});
  78. ~ImageDecoder() = default;
  79. IntSize size() const { return m_plugin->size(); }
  80. int width() const { return size().width(); }
  81. int height() const { return size().height(); }
  82. bool is_animated() const { return m_plugin->is_animated(); }
  83. size_t loop_count() const { return m_plugin->loop_count(); }
  84. size_t frame_count() const { return m_plugin->frame_count(); }
  85. size_t first_animated_frame_index() const { return m_plugin->first_animated_frame_index(); }
  86. ErrorOr<ImageFrameDescriptor> frame(size_t index, Optional<IntSize> ideal_size = {}) const { return m_plugin->frame(index, ideal_size); }
  87. Optional<Metadata const&> metadata() const { return m_plugin->metadata(); }
  88. ErrorOr<Optional<ReadonlyBytes>> icc_data() const { return m_plugin->icc_data(); }
  89. NaturalFrameFormat natural_frame_format() { return m_plugin->natural_frame_format(); }
  90. // Call only if natural_frame_format() == NaturalFrameFormat::CMYK.
  91. ErrorOr<NonnullRefPtr<CMYKBitmap>> cmyk_frame() { return m_plugin->cmyk_frame(); }
  92. // Call only if natural_frame_format() == NaturalFrameFormat::Vector.
  93. ErrorOr<VectorImageFrameDescriptor> vector_frame(size_t index) { return m_plugin->vector_frame(index); }
  94. private:
  95. explicit ImageDecoder(NonnullOwnPtr<ImageDecoderPlugin>);
  96. NonnullOwnPtr<ImageDecoderPlugin> mutable m_plugin;
  97. };
  98. }