ronantakizawa/codereview-bench huggingface dataset:
Repository: xbmc/xbmc
File: xbmc/music/MusicDatabase.cpp (C++)

Code before:

    while (!m_pDS->eof())
    {
      artTypes.emplace_back(m_pDS->fv(0).get_asString());
      m_pDS->next();
    }
    m_pDS->close();
    return true;
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, mediaType.c_str());
  }
  return false;
}

std::vector<std::string> CMusicDatabase::GetAvailableArtTypesForItem(int mediaId,
  const MediaType& mediaType)
{
  std::vector<std::string> result;
  if (mediaType == MediaTypeArtist)
  {
    CArtist artist;
    if (GetArtist(mediaId, artist))
    {
      /// @deprecated artwork: fanart stored separately, doesn't need to be
      if (artist.fanart.GetNumFanarts())
        result.push_back("fanart");

      // all other images
      for (const auto& urlEntry : artist.thumbURL.m_url)
      {
        std::string artType = urlEntry.m_aspect;
        if (artType.empty())
          artType = "thumb";
        if (std::find(result.begin(), result.end(), artType) == result.end())
          result.push_back(artType);
      }
    }
  }
  else if (mediaType == MediaTypeAlbum)
  {
    CAlbum album;
    if (GetAlbum(mediaId, album))
    {
      for (const auto& urlEntry : album.thumbURL.m_url)
      {
        std::string artType = urlEntry.m_aspect;
        if (artType.empty())
          artType = "thumb";
        if (std::find(result.begin(), result.end(), artType) == result.end())

Review comment (suggestion):
Better as  a doxygen `//! @todo` 
Maybe raise a roadmap issue too for artist fanart to be handled along with all the other types of art, so it does not get forgotten

Code after:

    while (!m_pDS->eof())
    {
      artTypes.emplace_back(m_pDS->fv(0).get_asString());
      m_pDS->next();
    }
    m_pDS->close();
    return true;
  }
  catch (...)
  {
    CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, mediaType.c_str());
  }
  return false;
}

std::vector<std::string> CMusicDatabase::GetAvailableArtTypesForItem(int mediaId,
  const MediaType& mediaType)
{
  std::vector<std::string> result;
  if (mediaType == MediaTypeArtist)
  {
    CArtist artist;
    if (GetArtist(mediaId, artist))
    {
      //! @todo artwork: fanart stored separately, doesn't need to be
      if (artist.fanart.GetNumFanarts())
        result.push_back("fanart");

      // all other images
      for (const auto& urlEntry : artist.thumbURL.m_url)
      {
        std::string artType = urlEntry.m_aspect;
        if (artType.empty())
          artType = "thumb";
        if (std::find(result.begin(), result.end(), artType) == result.end())
          result.push_back(artType);
      }
    }
  }
  else if (mediaType == MediaTypeAlbum)
  {
    CAlbum album;
    if (GetAlbum(mediaId, album))
    {
      for (const auto& urlEntry : album.thumbURL.m_url)
      {
        std::string artType = urlEntry.m_aspect;
        if (artType.empty())
          artType = "thumb";
        if (std::find(result.begin(), result.end(), artType) == result.end())
Repository: xbmc/xbmc
File: xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPBaseRenderer.cpp (C++)

Code before:
/*
 *  Copyright (C) 2017-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "RPBaseRenderer.h"
#include "ServiceBroker.h"
#include "windowing/GraphicContext.h"
#include "windowing/WinSystem.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "cores/RetroPlayer/buffers/IRenderBuffer.h"
#include "cores/RetroPlayer/buffers/IRenderBufferPool.h"
#include "cores/RetroPlayer/rendering/RenderContext.h"
#include "cores/RetroPlayer/rendering/RenderUtils.h"
#include "utils/log.h"

using namespace KODI;
using namespace RETRO;

// Consider renderer visible until this many frames have passed without rendering
#define VISIBLE_DURATION_FRAME_COUNT 1

CRPBaseRenderer::CRPBaseRenderer(const CRenderSettings& renderSettings,
                                 CRenderContext& context,
                                 std::shared_ptr<IRenderBufferPool> bufferPool)
  : m_context(context), m_bufferPool(std::move(bufferPool)), m_renderSettings(renderSettings)
{
  m_bufferPool->RegisterRenderer(this);
}

CRPBaseRenderer::~CRPBaseRenderer()

Review comment (suggestion):
A design constraint is that ServiceBroker.h isn't allowed in this file. See how other singletons are handled.

Code after:
/*
 *  Copyright (C) 2017-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "RPBaseRenderer.h"

#include "cores/RetroPlayer/buffers/IRenderBuffer.h"
#include "cores/RetroPlayer/buffers/IRenderBufferPool.h"
#include "cores/RetroPlayer/rendering/RenderContext.h"
#include "cores/RetroPlayer/rendering/RenderUtils.h"
#include "utils/log.h"

using namespace KODI;
using namespace RETRO;

// Consider renderer visible until this many frames have passed without rendering
#define VISIBLE_DURATION_FRAME_COUNT 1

CRPBaseRenderer::CRPBaseRenderer(const CRenderSettings& renderSettings,
                                 CRenderContext& context,
                                 std::shared_ptr<IRenderBufferPool> bufferPool)
  : m_context(context), m_bufferPool(std::move(bufferPool)), m_renderSettings(renderSettings)
{
  m_bufferPool->RegisterRenderer(this);
}

CRPBaseRenderer::~CRPBaseRenderer()
{
  SetBuffer(nullptr);

  m_bufferPool->UnregisterRenderer(this);
Repository: xbmc/xbmc
File: xbmc/windowing/gbm/DRMAtomic.cpp (C++)

Code before:

#include "DRMAtomic.h"

#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
#include "settings/Settings.h"
#include "utils/log.h"

#include <errno.h>
#include <string.h>

#include <drm_fourcc.h>
#include <drm_mode.h>
#include <unistd.h>

using namespace KODI::WINDOWING::GBM;

void CDRMAtomic::DrmAtomicCommit(int fb_id, int flags, bool rendered, bool videoLayer)
{
  uint32_t blob_id;

  if (flags & DRM_MODE_ATOMIC_ALLOW_MODESET)
  {
    if (!AddProperty(m_connector, "CRTC_ID", m_crtc->crtc->crtc_id))
    {
      return;
    }

    if (drmModeCreatePropertyBlob(m_fd, m_mode, sizeof(*m_mode), &blob_id) != 0)
    {
      return;
    }

    if (m_active && m_orig_crtc && m_orig_crtc->crtc->crtc_id != m_crtc->crtc->crtc_id)
    {
      // if using a different CRTC than the original, disable original to avoid EINVAL
      if (!AddProperty(m_orig_crtc, "MODE_ID", 0))
      {
        return;
      }
      if (!AddProperty(m_orig_crtc, "ACTIVE", 0))
      {
        return;
      }
    }

    if (!AddProperty(m_crtc, "MODE_ID", blob_id))
    {
      return;
    }

Review comment (bug):
This incorrectly hard-codes the values of the DRM enum here.

The uAPI doesn't have this guarantee, e.g. "Nearest Neighbor" could be exposed as the integer 5 in some other driver.

Code after:

#include "DRMAtomic.h"

#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
#include "utils/log.h"

#include <errno.h>
#include <string.h>

#include <drm_fourcc.h>
#include <drm_mode.h>
#include <unistd.h>

using namespace KODI::WINDOWING::GBM;

const std::string CDRMAtomic::SETTING_VIDEOSCREEN_HW_SCALING_FILTER = "videoscreen.hwscalingfilter";

enum drm_scaling_filter
{
  DRM_SCALING_FILTER_DEFAULT,
  DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
};

uint32_t CDRMAtomic::GetScalingFilterType(const char* type)
{
  if (!strcmp(type, "Nearest Neighbor"))
    return DRM_SCALING_FILTER_NEAREST_NEIGHBOR;
  else
    return DRM_SCALING_FILTER_DEFAULT;
}

uint32_t CDRMAtomic::GetScalingFactor(uint32_t srcWidth,
                                      uint32_t srcHeight,
                                      uint32_t destWidth,
                                      uint32_t destHeight)
{
  uint32_t factor_W = destWidth / srcWidth;
  uint32_t factor_H = destHeight / srcHeight;
  if (factor_W != factor_H)
    return (factor_W < factor_H) ? factor_W : factor_H;
  return factor_W;
}

bool CDRMAtomic::SetScalingFilter(struct drm_object* object, const char* name, const char* type)
{
  uint32_t filter_type = GetScalingFilterType(type);
Repository: xbmc/xbmc
File: xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.h (C/C++)

Code before:
struct SInfo
{
  std::string line[MAX_LINES];
};

class CDVDOverlayText;

class CDebugRenderer
{
public:
  CDebugRenderer();
  virtual ~CDebugRenderer();
  void SetInfo(SInfo& info);
  void Render(CRect &src, CRect &dst, CRect &view);
  void Flush();

protected:

  class CRenderer : public OVERLAY::CRenderer
  {
  public:
    CRenderer();
    void Render(int idx) override;
  };

  std::string m_strDebug[MAX_LINES];
  CDVDOverlayText* m_overlay[MAX_LINES];
  CRenderer m_overlayRenderer;
};


Review comment (refactor):
I think `std::array<std::string, MAX_LINES>` would be better or even better would be to use `std::vector<std::string>` as we don't have a defined size at compile time. This would also simplify some of the interface methods

Code after:
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "DebugInfo.h"
#include "OverlayRenderer.h"

#include <string>

class CDVDOverlayText;

class CDebugRenderer
{
public:
  CDebugRenderer();
  virtual ~CDebugRenderer();
  void SetInfo(DEBUG_INFO_PLAYER& info);
  void SetInfo(DEBUG_INFO_VIDEO& video, DEBUG_INFO_RENDER& render);
  void Render(CRect& src, CRect& dst, CRect& view);
  void Flush();

protected:

  class CRenderer : public OVERLAY::CRenderer
  {
  public:
    CRenderer();
    void Render(int idx) override;
  };

  std::string m_strDebug[6];
  CDVDOverlayText* m_overlay[6];
  CRenderer m_overlayRenderer;
};
Repository: xbmc/xbmc
File: xbmc/utils/EGLUtils.cpp (C++)

Code before:
{
  if (!CEGLUtils::HasExtension(m_eglDisplay, "EGL_KHR_partial_update"))
    return;

  std::vector<EGLint> rects;
  if (dirtyRegions.empty())
  {
    rects.push_back((EGLint)0);
    rects.push_back((EGLint)0);
    rects.push_back((EGLint)0);
    rects.push_back((EGLint)0);
  }
  else
  {
    EGLint height = CServiceBroker().GetWinSystem()->GetHeight();
    for (const auto& i : dirtyRegions)
    {
      if (i.IsEmpty())
        continue;
      rects.push_back((EGLint)i.x1);
      rects.push_back(height - (EGLint)i.y2);
      rects.push_back((EGLint)i.Width());
      rects.push_back((EGLint)i.Height());
    }
  }
  m_eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, rects.data(), rects.size() / 4);
}


Review comment (suggestion):
This could be a little bit faster but I can't test it lacking a GPU with `EGL_KHR_partial_update`.
```suggestion
  using Rect = std::array<EGLint, 4>;

  if (dirtyRegions.empty())
  {
    static Rect zeroRect{};
    m_eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, zeroRect.data(), 1);
  }
  else
  {
    EGLint height = CServiceBroker().GetWinSystem()->GetHeight();
    std::vector<Rect> rects;
    rects.reserve(dirtyRegions.size());
    for (const auto& i : dirtyRegions)
    {
      if (i.IsEmpty())
        continue;
      rects.push_back({(EGLint)i.x1, height - (EGLint)i.y2, (EGLint)i.Width(), (EGLint)i.Height()});
    }
    m_eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, reinterpret_cast<EGLint*>(rects.data()),
                            rects.size());
  }
```

Code after:
{
  if (m_eglDisplay == EGL_NO_DISPLAY || m_eglUploadContext == EGL_NO_CONTEXT)
  {
    CLog::LogF(LOGERROR, "No texture upload context found.");
    return false;
  }

  m_textureUploadLock.lock();

  if (!eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglUploadContext))
  {
    m_textureUploadLock.unlock();
    CLog::LogF(LOGERROR, "Couldn't bind texture upload context.");
    return false;
  }

  return true;
}

bool CEGLContextUtils::UnbindTextureUploadContext()
{
  if (m_eglDisplay == EGL_NO_DISPLAY || m_eglUploadContext == EGL_NO_CONTEXT)
  {
    CLog::LogF(LOGERROR, "No texture upload context found.");
    m_textureUploadLock.unlock();
    return false;
  }

  if (!eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
  {
    CLog::LogF(LOGERROR, "Couldn't release texture upload context");
    m_textureUploadLock.unlock();
    return false;
  }

  m_textureUploadLock.unlock();

  return true;
}

bool CEGLContextUtils::HasContext()
{
  return eglGetCurrentContext() != EGL_NO_CONTEXT;
}

void CEGLContextUtils::SetDamagedRegions(const CDirtyRegionList& dirtyRegions)
{
  if (!m_partialUpdateSupport)
    return;

  using Rect = std::array<EGLint, 4>;
Repository: xbmc/xbmc
File: xbmc/imagefiles/SpecialImageFileLoader.h (C/C++)

Code before:
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include <memory>
#include <string>

class CTexture;

namespace IMAGE_FILES
{

/*!
 * @brief An interface to load special image files into a texture for the cache.
 *
 * Special image files are generated or embedded images, like album covers embedded
 * in music files or thumbnails generated from video files.
*/
class ISpecialImageFileLoader
{
public:
  virtual bool CanLoad(std::string specialType) const = 0;
  virtual std::unique_ptr<CTexture> Load(
      std::string specialType,
      std::string filePath,
      unsigned int preferredWidth,
      unsigned int preferredHeight) const = 0;
  virtual ~ISpecialImageFileLoader() {}
};

} // namespace IMAGE_FILES

Review comment (suggestion):
I know this is legacy but in a future PR it would be nice if this was an enum class rather than a string.

Having an enum is much nicer for comparison and for tacking the available types.

Code after:
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include <memory>
#include <string>

class CTexture;

namespace IMAGE_FILES
{

/*!
 * @brief An interface to load special image files into a texture for the cache.
 *
 * Special image files are generated or embedded images, like album covers embedded
 * in music files or thumbnails generated from video files.
*/
class ISpecialImageFileLoader
{
public:
  virtual bool CanLoad(std::string specialType) const = 0;
  virtual std::unique_ptr<CTexture> Load(std::string specialType,
                                         std::string filePath,
                                         unsigned int preferredWidth,
                                         unsigned int preferredHeight) const = 0;
  virtual ~ISpecialImageFileLoader() = default;
};

} // namespace IMAGE_FILES
Repository: xbmc/xbmc
File: xbmc/imagefiles/SpecialImageFileLoader.h (C/C++)

Code before:
#pragma once

#include <memory>
#include <string>

class CTexture;

namespace IMAGE_FILES
{

/*!
 * @brief An interface to load special image files into a texture for the cache.
 *
 * Special image files are generated or embedded images, like album covers embedded
 * in music files or thumbnails generated from video files.
*/
class ISpecialImageFileLoader
{
public:
  virtual bool CanLoad(std::string specialType) const = 0;
  virtual std::unique_ptr<CTexture> Load(
      std::string specialType,
      std::string filePath,
      unsigned int preferredWidth,
      unsigned int preferredHeight) const = 0;
  virtual ~ISpecialImageFileLoader() {}
};

} // namespace IMAGE_FILES

Review comment (suggestion):
```suggestion
  virtual ~ISpecialImageFileLoader() = default;
```


Code after:
#pragma once

#include <memory>
#include <string>

class CTexture;

namespace IMAGE_FILES
{

/*!
 * @brief An interface to load special image files into a texture for the cache.
 *
 * Special image files are generated or embedded images, like album covers embedded
 * in music files or thumbnails generated from video files.
*/
class ISpecialImageFileLoader
{
public:
  virtual bool CanLoad(std::string specialType) const = 0;
  virtual std::unique_ptr<CTexture> Load(std::string specialType,
                                         std::string filePath,
                                         unsigned int preferredWidth,
                                         unsigned int preferredHeight) const = 0;
  virtual ~ISpecialImageFileLoader() = default;
};

} // namespace IMAGE_FILES
Repository: xbmc/xbmc
File: xbmc/music/MusicEmbeddedImageFileLoader.cpp (C++)

Code before:
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "MusicEmbeddedImageFileLoader.h"

#include "FileItem.h"
#include "guilib/Texture.h"
#include "music/tags/ImusicInfoTagLoader.h"
#include "music/tags/MusicInfoTag.h"
#include "music/tags/MusicInfoTagLoaderFactory.h"
#include "utils/EmbeddedArt.h"

using namespace MUSIC_INFO;

bool CMusicEmbeddedImageFileLoader::CanLoad(std::string specialType) const
{
  return specialType == "music";
}

namespace
{
bool GetEmbeddedThumb(const std::string& path, EmbeddedArt& art)
{
  CFileItem item(path, false);
  std::unique_ptr<IMusicInfoTagLoader> pLoader(CMusicInfoTagLoaderFactory::CreateLoader(item));
  CMusicInfoTag tag;
  if (nullptr != pLoader)
    pLoader->Load(path, tag, &art);

  return !art.Empty();
}
} // namespace

std::unique_ptr<CTexture> CMusicEmbeddedImageFileLoader::Load(
    std::string specialType,
    std::string filePath,
    unsigned int preferredWidth,
    unsigned int preferredHeight) const
{
  EmbeddedArt art;
  if (GetEmbeddedThumb(filePath, art))
    return CTexture::LoadFromFileInMemory(art.m_data.data(), art.m_size, art.m_mime,
        preferredWidth, preferredHeight);
  return nullptr;
}


Review comment (suggestion):
```suggestion
  std::unique_ptr<IMusicInfoTagLoader> loader(CMusicInfoTagLoaderFactory::CreateLoader(item));
```


Code after:
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "MusicEmbeddedImageFileLoader.h"

#include "FileItem.h"
#include "guilib/Texture.h"
#include "music/tags/ImusicInfoTagLoader.h"
#include "music/tags/MusicInfoTag.h"
#include "music/tags/MusicInfoTagLoaderFactory.h"
#include "utils/EmbeddedArt.h"

using namespace MUSIC_INFO;

bool CMusicEmbeddedImageFileLoader::CanLoad(std::string specialType) const
{
  return specialType == "music";
}

namespace
{
bool GetEmbeddedThumb(const std::string& path, EmbeddedArt& art)
{
  CFileItem item(path, false);
  std::unique_ptr<IMusicInfoTagLoader> loader(CMusicInfoTagLoaderFactory::CreateLoader(item));
  CMusicInfoTag tag;
  if (loader)
    loader->Load(path, tag, &art);

  return !art.Empty();
}
} // namespace

std::unique_ptr<CTexture> CMusicEmbeddedImageFileLoader::Load(std::string specialType,
                                                              std::string filePath,
                                                              unsigned int preferredWidth,
                                                              unsigned int preferredHeight) const
{
  EmbeddedArt art;
  if (GetEmbeddedThumb(filePath, art))
    return CTexture::LoadFromFileInMemory(art.m_data.data(), art.m_size, art.m_mime, preferredWidth,
                                          preferredHeight);
  return nullptr;
}
Repository: xbmc/xbmc
File: xbmc/video/VideoEmbeddedImageFileLoader.cpp (C++)

Code before:
 *  See LICENSES/README.md for more information.
 */

#include "VideoEmbeddedImageFileLoader.h"

#include "FileItem.h"
#include "guilib/Texture.h"
#include "utils/EmbeddedArt.h"
#include "utils/StringUtils.h"
#include "video/VideoInfoTag.h"
#include "video/tags/IVideoInfoTagLoader.h"
#include "video/tags/VideoInfoTagLoaderFactory.h"

using namespace VIDEO;

bool CVideoEmbeddedImageFileLoader::CanLoad(std::string specialType) const
{
  return StringUtils::StartsWith(specialType, "video_");
}

namespace
{
bool GetEmbeddedThumb(const std::string& path, const std::string& type, EmbeddedArt& art)
{
  CFileItem item(path, false);
  std::unique_ptr<IVideoInfoTagLoader> pLoader;
  pLoader.reset(CVideoInfoTagLoaderFactory::CreateLoader(item, ADDON::ScraperPtr(), false));
  CVideoInfoTag tag;
  std::vector<EmbeddedArt> artv;
  if (pLoader)
    pLoader->Load(tag, false, &artv);

  for (const EmbeddedArt& it : artv)
  {
    if (it.m_type == type)
    {
      art = it;
      break;
    }
  }
  return !art.Empty();
}
} // namespace

std::unique_ptr<CTexture> CVideoEmbeddedImageFileLoader::Load(
    std::string specialType,
    std::string filePath,
    unsigned int preferredWidth,
    unsigned int preferredHeight) const
{
  EmbeddedArt art;

Review comment (suggestion):
```suggestion
  std::unique_ptr<IVideoInfoTagLoader> loader;
```


Code after:
 *  See LICENSES/README.md for more information.
 */

#include "VideoEmbeddedImageFileLoader.h"

#include "FileItem.h"
#include "guilib/Texture.h"
#include "utils/EmbeddedArt.h"
#include "utils/StringUtils.h"
#include "video/VideoInfoTag.h"
#include "video/tags/IVideoInfoTagLoader.h"
#include "video/tags/VideoInfoTagLoaderFactory.h"

using namespace VIDEO;

bool CVideoEmbeddedImageFileLoader::CanLoad(std::string specialType) const
{
  return StringUtils::StartsWith(specialType, "video_");
}

namespace
{
bool GetEmbeddedThumb(const std::string& path, const std::string& type, EmbeddedArt& art)
{
  CFileItem item(path, false);
  std::unique_ptr<IVideoInfoTagLoader> loader(
      CVideoInfoTagLoaderFactory::CreateLoader(item, ADDON::ScraperPtr(), false));
  CVideoInfoTag tag;
  std::vector<EmbeddedArt> artv;
  if (loader)
    loader->Load(tag, false, &artv);

  for (const auto& it : artv)
  {
    if (it.m_type == type)
    {
      art = it;
      break;
    }
  }
  return !art.Empty();
}
} // namespace

std::unique_ptr<CTexture> CVideoEmbeddedImageFileLoader::Load(std::string specialType,
                                                              std::string filePath,
                                                              unsigned int preferredWidth,
                                                              unsigned int preferredHeight) const
{
  EmbeddedArt art;
  if (GetEmbeddedThumb(filePath, specialType.substr(6), art))