LCOV - code coverage report
Current view: top level - src/engraving/dom - imageStore.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 86.7 % 60 52
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #include "imageStore.h"
      24              : 
      25              : #include "io/path.h"
      26              : 
      27              : #include "image.h"
      28              : #include "score.h"
      29              : 
      30              : #include "log.h"
      31              : 
      32              : using namespace mu;
      33              : using namespace muse;
      34              : using namespace muse::io;
      35              : 
      36              : namespace mu::engraving {
      37              : ImageStore imageStore;  // the global image store
      38              : 
      39              : //---------------------------------------------------------
      40              : //   ImageStoreItem
      41              : //---------------------------------------------------------
      42              : 
      43            2 : ImageStoreItem::ImageStoreItem(const std::string& type)
      44            2 :     : m_type(type)
      45              : {
      46            2 : }
      47              : 
      48              : //---------------------------------------------------------
      49              : //   dereference
      50              : //    decrement usage count of image in score
      51              : //---------------------------------------------------------
      52              : 
      53           24 : void ImageStoreItem::dereference(Image* image)
      54              : {
      55           24 :     m_references.remove(image);
      56           24 : }
      57              : 
      58              : //---------------------------------------------------------
      59              : //   reference
      60              : //    increment usage count of image in score
      61              : //---------------------------------------------------------
      62              : 
      63           24 : void ImageStoreItem::reference(Image* image)
      64              : {
      65           24 :     m_references.push_back(image);
      66           24 : }
      67              : 
      68              : //---------------------------------------------------------
      69              : //   isUsed
      70              : //    check if item is used in score
      71              : //---------------------------------------------------------
      72              : 
      73            0 : bool ImageStoreItem::isUsed(Score* score) const
      74              : {
      75            0 :     for (Image* image : m_references) {
      76            0 :         if (image->score() == score && image->ownershipParent()) {
      77            0 :             return true;
      78              :         }
      79              :     }
      80            0 :     return false;
      81              : }
      82              : 
      83              : //---------------------------------------------------------
      84              : //   hashName
      85              : //---------------------------------------------------------
      86              : 
      87           19 : std::string ImageStoreItem::hashName() const
      88              : {
      89           19 :     const char hex[17] = "0123456789abcdef";
      90              :     char p[33];
      91          323 :     for (int i = 0; i < 16; ++i) {
      92          304 :         p[i * 2]     = hex[(m_hash[i] >> 4) & 0xf];
      93          304 :         p[i * 2 + 1] = hex[m_hash[i] & 0xf];
      94              :     }
      95           19 :     p[32] = 0;
      96           76 :     return std::string(p) + "." + m_type;
      97              : }
      98              : 
      99              : //---------------------------------------------------------
     100              : //   toInt
     101              : //---------------------------------------------------------
     102              : 
     103          672 : inline static int toInt(char c)
     104              : {
     105          672 :     if (c >= '0' && c <= '9') {
     106          441 :         return c - '0';
     107              :     }
     108          231 :     return c - 'a' + 10;
     109              : }
     110              : 
     111              : //---------------------------------------------------------
     112              : //   ~ImageStore
     113              : //---------------------------------------------------------
     114              : 
     115           19 : ImageStore::~ImageStore()
     116              : {
     117           19 :     muse::DeleteAll(m_items);
     118           19 : }
     119              : 
     120              : //---------------------------------------------------------
     121              : //   getImage
     122              : //---------------------------------------------------------
     123              : 
     124           21 : ImageStoreItem* ImageStore::getImage(std::string name) const
     125              : {
     126           21 :     name = muse::io::completeBasename(name).toStdString();
     127           21 :     if (name.size() != 32) {
     128            0 :         return nullptr;
     129              :     }
     130           21 :     ByteArray hash(16);
     131          357 :     for (int i = 0; i < 16; ++i) {
     132          336 :         hash[i] = toInt(name.at(i * 2)) * 16 + toInt(name.at(i * 2 + 1));
     133              :     }
     134           21 :     for (ImageStoreItem* item : m_items) {
     135           19 :         if (item->hash() == hash) {
     136           19 :             return item;
     137              :         }
     138              :     }
     139            2 :     LOGW() << "image not found: " << name;
     140            2 :     return nullptr;
     141           21 : }
     142              : 
     143              : //---------------------------------------------------------
     144              : //   add
     145              : //---------------------------------------------------------
     146              : 
     147            2 : ImageStoreItem* ImageStore::add(const std::string& name, const ByteArray& ba)
     148              : {
     149            2 :     ByteArray hash = cryptographicHash()->hash(ba, ICryptographicHash::Algorithm::Md4);
     150            2 :     for (ImageStoreItem* item : m_items) {
     151            0 :         if (item->hash() == hash) {
     152            0 :             return item;
     153              :         }
     154              :     }
     155            2 :     ImageStoreItem* item = new ImageStoreItem(muse::io::suffix(name));
     156            2 :     item->set(ba, hash);
     157            2 :     m_items.push_back(item);
     158            2 :     return item;
     159            2 : }
     160              : 
     161              : //---------------------------------------------------------
     162              : //   clearUnused
     163              : //---------------------------------------------------------
     164              : 
     165         2095 : void ImageStore::clearUnused()
     166              : {
     167         4190 :     m_items.erase(
     168         2095 :         std::remove_if(m_items.begin(), m_items.end(), [](ImageStoreItem* i) {
     169           14 :         const bool remove = !i->isUsed();
     170           14 :         if (remove) {
     171            2 :             delete i;
     172              :         }
     173           14 :         return remove;
     174              :     }),
     175         2095 :         m_items.end()
     176              :         );
     177         2095 : }
     178              : }
        

Generated by: LCOV version 2.0-1