Skip to content

Commit

Permalink
Fix zooming to selection
Browse files Browse the repository at this point in the history
* Fixed: zoom to selection should now work correctly with panning.
* Update the alternate JPEGView INIs.
* Default to filename order.
* Add toggle transparency to TGA & TIFF image types.
  • Loading branch information
sdneon committed Jan 22, 2023
1 parent 65383db commit 2111819
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/JPEGView/Config/JPEGView-windowed.ini
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ DownSamplingFilter=BestQuality

; Sorting order of the files when displaying the image files in a folder
; Can be LastModDate, CreationDate, FileName, FileSize or Random
FileDisplayOrder=LastModDate
FileDisplayOrder=FileName

; Sort files upcounting or downcounting
IsSortedUpcounting=true
Expand Down
2 changes: 1 addition & 1 deletion src/JPEGView/Config/JPEGView.ini
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ DownSamplingFilter=BestQuality

; Sorting order of the files when displaying the image files in a folder
; Can be LastModDate, CreationDate, FileName, FileSize or Random
FileDisplayOrder=LastModDate
FileDisplayOrder=FileName

; Sort files upcounting or downcounting
IsSortedUpcounting=true
Expand Down
5 changes: 2 additions & 3 deletions src/JPEGView/CropCtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,8 @@ CRect CCropCtl::GetImageCropRect(bool losslessCrop) {
if (pCurrentImage == NULL) {
return CRect(0, 0, 0, 0);
} else {
//CRect cropRect = CRect(max(0, min(m_cropStart.x, m_cropEnd.x)), max(0, min(m_cropStart.y, m_cropEnd.y)),
// min(pCurrentImage->OrigWidth(), max(m_cropStart.x, m_cropEnd.x) + 1), min(pCurrentImage->OrigHeight(), max(m_cropStart.y, m_cropEnd.y) + 1));

NormalizeCroppingRect();
//allow selection even if x/y is outside (negative value) of image
int x = m_cropStart.x, xEnd = m_cropEnd.x,
y = m_cropStart.y, yEnd = m_cropEnd.y,
selW = xEnd - x,
Expand Down
23 changes: 17 additions & 6 deletions src/JPEGView/ImageLoadThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "StdAfx.h"
#include "ImageLoadThread.h"
#include <gdiplus.h>
#include <GdiplusEnums.h>
#include "JPEGImage.h"
#include "MessageDef.h"
#include "Helpers.h"
Expand Down Expand Up @@ -148,7 +149,7 @@ static EImageFormat GetBitmapFormat(Gdiplus::Bitmap* pBitmap) {
}

static CJPEGImage* ConvertGDIPlusBitmapToJPEGImage(Gdiplus::Bitmap* pBitmap, int nFrameIndex, void* pEXIFData,
__int64 nJPEGHash, bool& isOutOfMemory, bool& isAnimatedGIF) {
__int64 nJPEGHash, bool& isOutOfMemory, bool& isAnimatedGIF, bool bUseCheckerboard = false) {

isOutOfMemory = false;
isAnimatedGIF = false;
Expand Down Expand Up @@ -205,8 +206,18 @@ static CJPEGImage* ConvertGDIPlusBitmapToJPEGImage(Gdiplus::Bitmap* pBitmap, int
pBmTarget = new Gdiplus::Bitmap(pBitmap->GetWidth(), pBitmap->GetHeight(), PixelFormat32bppRGB);
pBmGraphics = new Gdiplus::Graphics(pBmTarget);
COLORREF bkColor = CSettingsProvider::This().ColorTransparency();
Gdiplus::SolidBrush bkBrush(Gdiplus::Color(GetRValue(bkColor), GetGValue(bkColor), GetBValue(bkColor)));
pBmGraphics->FillRectangle(&bkBrush, 0, 0, pBmTarget->GetWidth(), pBmTarget->GetHeight());
if (!bUseCheckerboard)
{
//Somehow unlike WebpAlphaBlendBackground, needs to reverse the colour bytes!
//Gdiplus::SolidBrush bkBrush(Gdiplus::Color(GetRValue(bkColor), GetGValue(bkColor), GetBValue(bkColor)));
Gdiplus::SolidBrush bkBrush(Gdiplus::Color(GetBValue(bkColor), GetGValue(bkColor), GetRValue(bkColor)));
pBmGraphics->FillRectangle(&bkBrush, 0, 0, pBmTarget->GetWidth(), pBmTarget->GetHeight());
}
else
{
Gdiplus::HatchBrush bkBrush(HatchStyleLargeCheckerBoard, Gdiplus::Color(0xffc0c0c0), Gdiplus::Color(0xffffffff));
pBmGraphics->FillRectangle(&bkBrush, 0, 0, pBmTarget->GetWidth(), pBmTarget->GetHeight());
}
pBmGraphics->DrawImage(pBitmap, 0, 0, pBmTarget->GetWidth(), pBmTarget->GetHeight());
pBitmapToUse = pBmTarget;
if (pBmGraphics->GetLastStatus() == Gdiplus::OutOfMemory) {
Expand Down Expand Up @@ -491,7 +502,7 @@ void CImageLoadThread::ProcessReadJPEGRequest(CRequest* request) {
Gdiplus::Bitmap* pBitmap = Gdiplus::Bitmap::FromStream(pStream, CSettingsProvider::This().UseEmbeddedColorProfiles());
bool isOutOfMemory, isAnimatedGIF;
request->Image = ConvertGDIPlusBitmapToJPEGImage(pBitmap, 0, Helpers::FindEXIFBlock(pBuffer, nFileSize),
Helpers::CalculateJPEGFileHash(pBuffer, nFileSize), isOutOfMemory, isAnimatedGIF);
Helpers::CalculateJPEGFileHash(pBuffer, nFileSize), isOutOfMemory, isAnimatedGIF, request->ProcessParams.UseCheckerboard);
request->OutOfMemory = request->Image == NULL && isOutOfMemory;
if (request->Image != NULL) {
request->Image->SetJPEGComment(Helpers::GetJPEGComment(pBuffer, nFileSize));
Expand Down Expand Up @@ -792,7 +803,7 @@ void CImageLoadThread::ProcessReadBMPRequest(CRequest* request) {

void CImageLoadThread::ProcessReadTGARequest(CRequest* request) {
bool bOutOfMemory;
request->Image = CReaderTGA::ReadTgaImage(request->FileName, CSettingsProvider::This().ColorBackground(), bOutOfMemory);
request->Image = CReaderTGA::ReadTgaImage(request->FileName, CSettingsProvider::This().ColorTransparency(), bOutOfMemory, request->ProcessParams.UseCheckerboard);
if (bOutOfMemory) {
request->OutOfMemory = true;
}
Expand Down Expand Up @@ -987,7 +998,7 @@ void CImageLoadThread::ProcessReadGDIPlusRequest(CRequest* request) {
m_sLastFileName = sFileName;
}
bool isOutOfMemory, isAnimatedGIF;
request->Image = ConvertGDIPlusBitmapToJPEGImage(pBitmap, request->FrameIndex, NULL, 0, isOutOfMemory, isAnimatedGIF);
request->Image = ConvertGDIPlusBitmapToJPEGImage(pBitmap, request->FrameIndex, NULL, 0, isOutOfMemory, isAnimatedGIF, request->ProcessParams.UseCheckerboard);
request->OutOfMemory = request->Image == NULL && isOutOfMemory;
if (!isAnimatedGIF) {
DeleteCachedGDIBitmap();
Expand Down
22 changes: 19 additions & 3 deletions src/JPEGView/MainDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2898,9 +2898,25 @@ void CMainDlg::ZoomToSelection() {
float fZoom;
CPoint offsets;
Helpers::GetZoomParameters(fZoom, offsets, m_pCurrentImage->OrigSize(), m_clientRect.Size(), zoomRect);
if (fZoom > 0) {
PerformZoom(fZoom, false, m_bMouseOn, false);
m_offsets = offsets;
if (fZoom > 0)
{
/*
* Use bAdjustWindowToImage:true and bZoomToMouse for more accuracy,
* while faking the mouse position to centre of zoomRect.
*/
float x = zoomRect.left, y = zoomRect.top,
x2 = zoomRect.right, y2 = zoomRect.bottom;
//convert zoomRect in image coords back to win/screen coords
ImageToScreen(x, y);
ImageToScreen(x2, y2);
int oldMouseX = m_nMouseX,
oldMouseY = m_nMouseY;
//use centre of zoomRect (in win coords) as mouse position
m_nMouseX = (x2 + x) / 2;
m_nMouseY = (y2 + y) / 2;
PerformZoom(fZoom, false, true, true);
m_nMouseX = oldMouseX; //restore in case of adverse side effect
m_nMouseY = oldMouseY;
m_bUserPan = true;
}
}
Expand Down
40 changes: 32 additions & 8 deletions src/JPEGView/ReaderTGA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,30 @@ static bool IsAlphaChannelValid(int width, int height, uint32* pImageData)
return pixel != 0;
}

static inline uint32 AlphaBlendBackground(uint32 pixel, uint32 backgroundColor)
static inline uint32 AlphaBlendBackground(uint32 pixel, uint32 backgroundColor, bool bUseCheckerboard = false, int x = -1, int y = -1)
{
uint32 alpha = pixel & ALPHA_OPAQUE;
if (alpha == 0) {
return backgroundColor;
} else if (alpha == ALPHA_OPAQUE)
if (alpha == ALPHA_OPAQUE)
{
return pixel;
} else {
}
if (bUseCheckerboard)
{
//ignore configured backgroundColor, and use white and light gray for checkerboard
if (((x & 0x10) && ((y & 0x10) == 0))
|| ((y & 0x10) && ((x & 0x10) == 0)))
{
backgroundColor = 0x00ffffff;
}
else
{
backgroundColor = 0x00c0c0c0;
}
}
if (alpha == 0) {
return backgroundColor;
}
else {
uint8 b = GetBValue(pixel);
uint8 g = GetGValue(pixel);
uint8 r = GetRValue(pixel);
Expand All @@ -57,7 +72,7 @@ static inline uint32 AlphaBlendBackground(uint32 pixel, uint32 backgroundColor)
}


CJPEGImage* CReaderTGA::ReadTgaImage(LPCTSTR strFileName, COLORREF backgroundColor, bool& bOutOfMemory) {
CJPEGImage* CReaderTGA::ReadTgaImage(LPCTSTR strFileName, COLORREF backgroundColor, bool& bOutOfMemory, bool bUseCheckerboard) {

bOutOfMemory = false;

Expand Down Expand Up @@ -372,9 +387,18 @@ CJPEGImage* CReaderTGA::ReadTgaImage(LPCTSTR strFileName, COLORREF backgroundCol
uint32* pImage32 = (uint32*)pImageData;
if (IsAlphaChannelValid(width, height, (uint32*)pImageData))
{
for (int i = 0; i < width*height; i++)
if (!bUseCheckerboard)
{
for (int i = 0; i < width * height; ++i)
{
*pImage32++ = AlphaBlendBackground(*pImage32, backgroundColor | ALPHA_OPAQUE);
}
}
else
{
*pImage32++ = AlphaBlendBackground(*pImage32, backgroundColor | ALPHA_OPAQUE);
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
*pImage32++ = AlphaBlendBackground(*pImage32, backgroundColor | ALPHA_OPAQUE, true, x, y);
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/JPEGView/ReaderTGA.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class CReaderTGA
{
public:
// Returns NULL in case of errors. backgroundColor is used for blending transparent parts of the image.
static CJPEGImage* ReadTgaImage(LPCTSTR strFileName, COLORREF backgroundColor, bool& bOutOfMemory);
static CJPEGImage* ReadTgaImage(LPCTSTR strFileName, COLORREF backgroundColor, bool& bOutOfMemory, bool bUseCheckerboard);
private:
CReaderTGA(void);
};

0 comments on commit 2111819

Please sign in to comment.