LCOV - code coverage report
Current view: top level - core/bitmap - SPBitmapFormat.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 25 26 96.2 %
Date: 2024-05-12 00:16:13 Functions: 28 28 100.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_BITMAP_SPBITMAPFORMAT_H_
      25             : #define STAPPLER_BITMAP_SPBITMAPFORMAT_H_
      26             : 
      27             : #include "SPIO.h"
      28             : #include "SPBytesView.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler::bitmap {
      31             : 
      32             : class BitmapFormat;
      33             : 
      34             : enum class FileFormat {
      35             :         Png,
      36             :         Jpeg,
      37             :         WebpLossless,
      38             :         WebpLossy,
      39             :         Svg,
      40             :         Gif,
      41             :         Tiff,
      42             :         Custom
      43             : };
      44             : 
      45             : enum class AlphaFormat {
      46             :         Premultiplied,
      47             :         Unpremultiplied,
      48             :         Opaque,
      49             : };
      50             : 
      51             : enum class PixelFormat {
      52             :         Auto, // used by application, do not use with Bitmap directly
      53             :         A8,
      54             :         I8,
      55             :         IA88,
      56             :         RGB888,
      57             :         RGBA8888,
      58             : };
      59             : 
      60             : struct ImageInfo {
      61             :         PixelFormat color = PixelFormat::Auto;
      62             :         AlphaFormat alpha = AlphaFormat::Premultiplied;
      63             :         uint32_t width = 0;
      64             :         uint32_t height = 0;
      65             :         uint32_t stride = 0;
      66             : 
      67             :         const BitmapFormat *format = nullptr;
      68             : };
      69             : 
      70             : using StrideFn = Callback<uint32_t(PixelFormat, uint32_t)>;
      71             : 
      72             : bool getImageSize(StringView file, uint32_t &width, uint32_t &height);
      73             : bool getImageSize(const io::Producer &file, uint32_t &width, uint32_t &height);
      74             : 
      75             : bool getImageInfo(BytesView, ImageInfo &);
      76             : 
      77             : bool isImage(StringView file, bool readable = true);
      78             : bool isImage(const io::Producer &file, bool readable = true);
      79             : bool isImage(const uint8_t * data, size_t dataLen, bool readable = true);
      80             : 
      81             : Pair<FileFormat, StringView> detectFormat(StringView file);
      82             : Pair<FileFormat, StringView> detectFormat(const io::Producer &file);
      83             : Pair<FileFormat, StringView> detectFormat(const uint8_t * data, size_t dataLen);
      84             : 
      85             : StringView getMimeType(FileFormat);
      86             : StringView getMimeType(StringView);
      87             : 
      88             : bool check(FileFormat, const uint8_t * data, size_t dataLen);
      89             : bool check(StringView, const uint8_t * data, size_t dataLen);
      90             : 
      91        7337 : inline uint8_t getBytesPerPixel(PixelFormat c) {
      92        7337 :         switch (c) {
      93         578 :         case PixelFormat::A8: return 1; break;
      94         494 :         case PixelFormat::I8: return 1; break;
      95         753 :         case PixelFormat::IA88: return 2; break;
      96        3903 :         case PixelFormat::RGB888: return 3; break;
      97        1584 :         case PixelFormat::RGBA8888: return 4; break;
      98          25 :         case PixelFormat::Auto: return 0; break;
      99             :         }
     100           0 :         return 0;
     101             : }
     102             : 
     103             : template<PixelFormat Source, PixelFormat Target>
     104             : void convertLine(const uint8_t *in, uint8_t *out, uint32_t ins, uint32_t outs);
     105             : 
     106             : template<PixelFormat Source, PixelFormat Target>
     107        1213 : bool convertData(BytesView dataVec, BytesView out, uint32_t inStride, uint32_t outStride) {
     108        1213 :         auto dataLen = dataVec.size();
     109        1213 :         auto height = dataLen / inStride;
     110        1213 :         auto data = dataVec.data();
     111             :         // out.resize(height * outStride);
     112        1213 :         auto outData = (uint8_t *)out.data();
     113      366326 :         for (size_t j = 0; j < height; j ++) {
     114      365113 :                 convertLine<Source, Target>(data + inStride * j, outData + outStride * j, inStride, outStride);
     115             :         }
     116        1213 :         return true;
     117             : }
     118             : 
     119             : struct BitmapWriter : ImageInfo {
     120             :         void *target;
     121             : 
     122             :         uint32_t (*getStride) (void *, PixelFormat, uint32_t);
     123             : 
     124             :         void (*push) (void *, const uint8_t *, uint32_t);
     125             :         void (*resize) (void *, uint32_t size);
     126             :         uint8_t * (*getData) (void *, uint32_t location);
     127             :         void (*assign) (void *, const uint8_t *, uint32_t);
     128             :         void (*clear) (void *);
     129             : };
     130             : 
     131             : class BitmapFormat {
     132             : public:
     133             :         enum Flags {
     134             :                 None = 0,
     135             :                 Recognizable = 1 << 0,
     136             :                 Readable = 1 << 1,
     137             :                 Writable = 1 << 2,
     138             :         };
     139             : 
     140             :         using check_fn = bool (*) (const uint8_t * data, size_t dataLen);
     141             :         using size_fn = bool (*) (const io::Producer &file, StackBuffer<512> &, uint32_t &width, uint32_t &height);
     142             :         using info_fn = bool (*) (const uint8_t *data, size_t size, ImageInfo &);
     143             :         using load_fn = bool (*) (const uint8_t *data, size_t size, BitmapWriter &);
     144             :         using write_fn = bool (*) (const uint8_t *data, BitmapWriter &, bool invert);
     145             :         using save_fn = bool (*) (StringView, const uint8_t *data, BitmapWriter &, bool invert);
     146             : 
     147             :         static void add(BitmapFormat &&);
     148             : 
     149             :         BitmapFormat(FileFormat, const check_fn&, const size_fn &, const info_fn & = nullptr,
     150             :                         const load_fn & = nullptr, const write_fn & = nullptr, const save_fn & = nullptr);
     151             : 
     152             :         BitmapFormat(StringView name, StringView mime, const check_fn&, const size_fn &, const info_fn & = nullptr,
     153             :                         const load_fn & = nullptr, const write_fn & = nullptr, const save_fn & = nullptr);
     154             : 
     155        5577 :         StringView getName() const { return _name; }
     156         700 :         StringView getMime() const { return _mime; }
     157             : 
     158             :         bool isRecognizable() const;
     159             :         bool isReadable() const;
     160             :         bool isWritable() const;
     161             : 
     162             :         Flags getFlags() const { return _flags; }
     163        1500 :         FileFormat getFormat() const { return _format; }
     164             : 
     165             :         bool is(const uint8_t * data, size_t dataLen) const;
     166             :         bool getSize(const io::Producer &file, StackBuffer<512> &, uint32_t &width, uint32_t &height) const;
     167             : 
     168             :         bool getInfo(const uint8_t *data, size_t size, ImageInfo &) const;
     169             : 
     170             :         bool load(const uint8_t *data, size_t size, BitmapWriter &) const;
     171             : 
     172             :         bool write(const uint8_t *data, BitmapWriter &, bool invert) const;
     173             : 
     174             :         bool save(StringView, const uint8_t *data,  BitmapWriter &, bool invert) const;
     175             : 
     176        1400 :         check_fn getCheckFn() const { return check_ptr; }
     177         400 :         size_fn getSizeFn() const { return size_ptr; }
     178         350 :         info_fn getInfoFn() const { return info_ptr; }
     179         350 :         load_fn getLoadFn() const { return load_ptr; }
     180         400 :         write_fn getWriteFn() const { return write_ptr; }
     181         400 :         save_fn getSaveFn() const { return save_ptr; }
     182             : 
     183             : protected:
     184             :         check_fn check_ptr = nullptr;
     185             :         size_fn size_ptr = nullptr;
     186             :         info_fn info_ptr = nullptr;
     187             :         load_fn load_ptr = nullptr;
     188             :         write_fn write_ptr = nullptr;
     189             :         save_fn save_ptr = nullptr;
     190             : 
     191             :         Flags _flags = None;
     192             :         FileFormat _format = FileFormat::Custom;
     193             :         StringView _name;
     194             :         StringView _mime;
     195             : };
     196             : 
     197             : SP_DEFINE_ENUM_AS_MASK(BitmapFormat::Flags)
     198             : 
     199             : }
     200             : 
     201             : #endif /* STAPPLER_BITMAP_SPBITMAPFORMAT_H_ */

Generated by: LCOV version 1.14