Skip to content

Commit

Permalink
Show correct image format in the file list
Browse files Browse the repository at this point in the history
Don't treat JPEG and PNG as video stream in FFmpeg frame grabber
  • Loading branch information
zenden2k committed Jun 12, 2023
1 parent 0dd09f1 commit 05b2666
Show file tree
Hide file tree
Showing 18 changed files with 174 additions and 89 deletions.
6 changes: 5 additions & 1 deletion Dist/iu_setup_script.iss
Expand Up @@ -155,8 +155,12 @@ begin
end;
procedure ShellExtBeforeInstall();
var
dest: String;
begin
RenameFile(ExpandConstant(CurrentFileName), ExpandConstant(CurrentFileName) + '.' + IntToStr(Random(100000)) + '.old');
dest := ExpandConstant(CurrentFileName) + '.' + IntToStr(Random(100000)) + '.old';
RenameFile(ExpandConstant(CurrentFileName), dest);
DeleteFile(dest)
end;
function GetIconFileName(Param: String): String;
Expand Down
10 changes: 9 additions & 1 deletion Source/Core/Images/AbstractImage.cpp
Expand Up @@ -34,4 +34,12 @@ bool AbstractImage::loadFromFile(const std::string& fileName)

const std::string& AbstractImage::factoryName() {
return factoryName_;
}
}

void AbstractImage::setSrcFormat(const std::string& str) {
srcFormat_ = str;
}

std::string AbstractImage::getSrcFormat() const {
return srcFormat_;
}
4 changes: 3 additions & 1 deletion Source/Core/Images/AbstractImage.h
Expand Up @@ -25,7 +25,7 @@ class AbstractImage
virtual int getHeight() const;
virtual bool isNull() const = 0;
virtual bool loadFromRawData(DataFormat dt, int width, int height, uint8_t* data, size_t dataSize, void* parameter) = 0;

std::string getSrcFormat() const;
template<class T> static void registerFactory(const char* name) {
factory_ = [] () -> AbstractImage* {
return new T();
Expand All @@ -42,11 +42,13 @@ class AbstractImage
}
static const std::string& factoryName();
static AbstractImage* createImage();
void setSrcFormat(const std::string& str);
protected:
static std::function<AbstractImage*()> factory_;
static std::string factoryName_;
int width_;
int height_;
std::string srcFormat_;
DISALLOW_COPY_AND_ASSIGN(AbstractImage);
};

Expand Down
12 changes: 6 additions & 6 deletions Source/Core/Images/GdiPlusImage.cpp
Expand Up @@ -27,7 +27,7 @@ void GdiPlusImage::init()
width_ = 0;
height_ = 0;
takeOwnership_ = true;
isSrcAnimated_ = false;
isSrcMultiFrame_ = false;
}

GdiPlusImage::~GdiPlusImage() {
Expand Down Expand Up @@ -170,10 +170,10 @@ Gdiplus::Bitmap* GdiPlusImage::releaseBitmap() {
return bm_;
}

void GdiPlusImage::setSrcAnimated(bool animated) {
isSrcAnimated_ = animated;
void GdiPlusImage::setSrcMultiFrame(bool animated) {
isSrcMultiFrame_ = animated;
}

bool GdiPlusImage::isSrcAnimated() const {
return isSrcAnimated_;
}
bool GdiPlusImage::isSrcMultiFrame() const {
return isSrcMultiFrame_;
}
6 changes: 3 additions & 3 deletions Source/Core/Images/GdiPlusImage.h
Expand Up @@ -22,13 +22,13 @@ class GdiPlusImage: public AbstractImage

int getWidth() const override;
int getHeight() const override;
void setSrcAnimated(bool animated);
bool isSrcAnimated() const;
void setSrcMultiFrame(bool animated);
bool isSrcMultiFrame() const;
protected:
Gdiplus::Bitmap* bm_;
uint8_t* data_;
bool takeOwnership_;
bool isSrcAnimated_;
bool isSrcMultiFrame_;
void init();
DISALLOW_COPY_AND_ASSIGN(GdiPlusImage);
};
Expand Down
8 changes: 7 additions & 1 deletion Source/Core/Images/GdiplusImageReader.cpp
Expand Up @@ -2,6 +2,7 @@

#include "Utils.h"
#include "Func/WinUtils.h"
#include "Core/Utils/CoreUtils.h"

typedef IStream * (STDAPICALLTYPE *SHCreateMemStreamFuncType)(const BYTE *pInit, UINT cbInit);

Expand Down Expand Up @@ -71,5 +72,10 @@ bool GdiplusImageReader::checkLastStatus(Gdiplus::Bitmap* bm) {
void GdiplusImageReader::postLoad(GdiPlusImage* bm) {
short orient = ImageUtils::GetImageOrientation(bm->getBitmap());
ImageUtils::RotateAccordingToOrientation(orient, bm->getBitmap(), true);
bm->setSrcAnimated(ImageUtils::IsImageAnimated(bm->getBitmap()));
bm->setSrcMultiFrame(ImageUtils::IsImageMultiFrame(bm->getBitmap()));
GUID format;
if (bm->getBitmap()->GetRawFormat(&format) == Gdiplus::Ok) {
bm->setSrcFormat(W2U(ImageUtils::ImageFormatGUIDToString(format)));
}

}
6 changes: 3 additions & 3 deletions Source/Core/Images/ImageConverterPrivate_gdiplus.cpp
@@ -1,4 +1,4 @@
#include "ImageConverterPrivate_gdiplus.h"
#include "ImageConverterPrivate_gdiplus.h"

#include <cassert>
#include <memory>
Expand Down Expand Up @@ -58,7 +58,7 @@ bool ImageConverterPrivate::convert(const std::string& sourceFile)
processingEnabled_ = false;
}

if (m_imageConvertingParams.SkipAnimated && srcImg->isSrcAnimated()) {
if (m_imageConvertingParams.SkipAnimated && srcImg->isSrcMultiFrame()) {
processingEnabled_ = false;
}

Expand Down Expand Up @@ -603,4 +603,4 @@ void ImageConverterPrivate::calcCropSize(int srcWidth, int srcHeight, CRect targ

destRect = rectDrawing;
srcRect = CRect(0,0, srcWidth, srcHeight);
}
}
6 changes: 3 additions & 3 deletions Source/Core/Images/Tests/UtilsTest.cpp
Expand Up @@ -476,12 +476,12 @@ TEST_F(UtilsTest, IsImageAnimated) {
{
Gdiplus::Image img(U2W(TestHelpers::resolvePath("Images/animation.gif")));
ASSERT_EQ(Gdiplus::Ok, img.GetLastStatus());
EXPECT_TRUE(IsImageAnimated(&img));
EXPECT_TRUE(IsImageMultiFrame(&img));
}
{

Gdiplus::Image img(U2W(TestHelpers::resolvePath("file_with_const_size.png")));
ASSERT_EQ(Gdiplus::Ok, img.GetLastStatus());
EXPECT_FALSE(IsImageAnimated(&img));
EXPECT_FALSE(IsImageMultiFrame(&img));
}
}
}
65 changes: 56 additions & 9 deletions Source/Core/Images/Utils.cpp
Expand Up @@ -397,7 +397,7 @@ void ApplyPixelateEffect(Gdiplus::Bitmap* bm, int xPos, int yPos, int w, int h,

}

std::unique_ptr<Gdiplus::Bitmap> LoadImageFromFileWithoutLocking(const WCHAR* fileName, bool* isAnimated) {
std::unique_ptr<Gdiplus::Bitmap> LoadImageFromFileWithoutLocking(const WCHAR* fileName, bool* isMultiFrame) {
using namespace Gdiplus;
auto img = LoadImageFromFileExtended(fileName);
if (!img) {
Expand All @@ -407,8 +407,8 @@ std::unique_ptr<Gdiplus::Bitmap> LoadImageFromFileWithoutLocking(const WCHAR* fi
if ( !src || src->GetLastStatus() != Ok ) {
return nullptr;
}
if (isAnimated) {
*isAnimated = img->isSrcAnimated();
if (isMultiFrame) {
*isMultiFrame = img->isSrcMultiFrame();
}
std::unique_ptr<Gdiplus::Bitmap> dst = std::make_unique<Bitmap>(src->GetWidth(), src->GetHeight(), PixelFormat32bppARGB);

Expand Down Expand Up @@ -1032,7 +1032,7 @@ std::unique_ptr<Gdiplus::Bitmap> GetThumbnail(Gdiplus::Image* bm, int width, int
return res;
}

std::unique_ptr<Gdiplus::Bitmap> GetThumbnail(const CString& filename, int width, int height, Gdiplus::Size* realSize) {
std::unique_ptr<Gdiplus::Bitmap> GetThumbnail(const CString& filename, int width, int height, Gdiplus::Size* realSize, CString* imageFormat) {
using namespace Gdiplus;
std::unique_ptr<GdiPlusImage> img = LoadImageFromFileExtended(filename);
if (!img) {
Expand All @@ -1044,7 +1044,11 @@ std::unique_ptr<Gdiplus::Bitmap> GetThumbnail(const CString& filename, int width
if (!bm || bm->GetLastStatus() != Ok) {
return {};
}
return GetThumbnail(bm.get(), width, height, realSize);
std::unique_ptr<Gdiplus::Bitmap> res = GetThumbnail(bm.get(), width, height, realSize);
if (res && imageFormat) {
*imageFormat = U2W(img->getSrcFormat());
}
return res;
}

Gdiplus::Size AdaptProportionalSize(const Gdiplus::Size& szMax, const Gdiplus::Size& szReal)
Expand Down Expand Up @@ -1421,16 +1425,22 @@ bool ExUtilReadFile(const wchar_t* const file_name, uint8_t** data, size_t* data
return true;
}

bool IsImageAnimated(Gdiplus::Image* img) {
bool IsImageMultiFrame(Gdiplus::Image* img) {
/*GUID format;
if (img->GetRawFormat(&format) == Gdiplus::Ok) {
if (format == ImageFormatTIFF) {
return false;
}
}*/

UINT count = img->GetFrameDimensionsCount();
GUID* pDimensionIDs = new GUID[count];
auto pDimensionIDs = std::make_unique<GUID[]>(count);

// Get the list of frame dimensions from the Image object.
img->GetFrameDimensionsList(pDimensionIDs, count);
img->GetFrameDimensionsList(pDimensionIDs.get(), count);

// Get the number of frames in the first dimension.
int frameCount = img->GetFrameCount(&pDimensionIDs[0]);
delete[] pDimensionIDs;
return frameCount > 1;
}

Expand Down Expand Up @@ -1532,4 +1542,41 @@ std::unique_ptr<Gdiplus::Font> StringToGdiplusFont(LPCTSTR szBuffer) {
return std::make_unique<Font>(&fontFamily, static_cast<REAL>(nFontSize), style, Gdiplus::UnitPixel);
}

CString ImageFormatGUIDToString(GUID guid) {
if (guid == ImageFormatBMP) {
return "bmp";
}
if (guid == ImageFormatEMF) {
return "emf";
}
if (guid == ImageFormatEXIF) {
return "exif";
}
if (guid == ImageFormatGIF) {
return "gif";
}
if (guid == ImageFormatIcon) {
return "ico";
}
if (guid == ImageFormatJPEG) {
return "jpeg";
}
if (guid == ImageFormatMemoryBMP) {
return "bmp";
}
if (guid == ImageFormatPNG) {
return "png";
}
if (guid == ImageFormatTIFF) {
return "tiff";
}
if (guid == ImageFormatWEBP) {
return "webp";
}
if (guid == ImageFormatWMF) {
return "wmf";
}
return "unknown";
}

}
5 changes: 3 additions & 2 deletions Source/Core/Images/Utils.h
Expand Up @@ -55,7 +55,7 @@ void ChangeAlphaChannel(Gdiplus::Bitmap& source, Gdiplus::Bitmap& dest, int sour
Gdiplus::Rect MeasureDisplayString(Gdiplus::Graphics& graphics, CString text, Gdiplus::RectF boundingRect, Gdiplus::Font& font);
CRect CenterRect(CRect r1, const CRect& intoR2);
std::unique_ptr<Gdiplus::Bitmap> GetThumbnail(Gdiplus::Image* bm, int width, int height, Gdiplus::Size* realSize = 0);
std::unique_ptr<Gdiplus::Bitmap> GetThumbnail(const CString& filename, int width, int height, Gdiplus::Size* realSize = 0);
std::unique_ptr<Gdiplus::Bitmap> GetThumbnail(const CString& filename, int width, int height, Gdiplus::Size* realSize = 0, CString* imageFormat = nullptr);
Gdiplus::Size AdaptProportionalSize(const Gdiplus::Size& szMax, const Gdiplus::Size& szReal);
std::unique_ptr<Gdiplus::Bitmap> BitmapFromMemory(BYTE* data, size_t size);

Expand All @@ -74,14 +74,15 @@ bool RotateAccordingToOrientation(short orient, Gdiplus::Image* img, bool remove
ImageInfo GetImageInfo(const wchar_t* fileName);

CString GdiplusStatusToString(Gdiplus::Status statusID);
bool IsImageAnimated(Gdiplus::Image* img);
bool IsImageMultiFrame(Gdiplus::Image* img);

/**
* @throws IOException
*/
bool SaveBitmapAsWebp(Gdiplus::Bitmap* img, CString fileName, IStream* stream, bool lossless, int quality);

std::unique_ptr<Gdiplus::Font> StringToGdiplusFont(LPCTSTR szBuffer);
CString ImageFormatGUIDToString(GUID guid);
}

#endif
5 changes: 3 additions & 2 deletions Source/Core/Images/WebpImageReader.cpp
Expand Up @@ -24,7 +24,7 @@ std::unique_ptr<GdiPlusImage> WebpImageReader::readFromFile(const wchar_t* fileN
size_t dataSize = 0;
try {
if (!ImageUtils::ExUtilReadFile(fileName, &dataRaw, &dataSize)) {
return nullptr;
return {};
}
} catch (const std::exception&) {
return {};
Expand Down Expand Up @@ -58,7 +58,8 @@ std::unique_ptr<GdiPlusImage> WebpImageReader::readFromMemory(uint8_t* data, siz
else {
WebPFree(pic.rgba);
}
img->setSrcAnimated(pic.animated);
img->setSrcMultiFrame(pic.animated);
img->setSrcFormat("webp");
return img;
}

Expand Down

0 comments on commit 05b2666

Please sign in to comment.