2021-10-01: Updated to version 1.64
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
parent
523b8ba30d
commit
8f505d8844
19 changed files with 1422 additions and 526 deletions
BIN
Emu48.exe
BIN
Emu48.exe
Binary file not shown.
15
Emu48.htm
15
Emu48.htm
|
@ -113,6 +113,21 @@ h3 { color:red; font-size:1.1em; }
|
|||
into the native Emu48 ROM format is not necessary any more. You can
|
||||
still use the classic way extracting them from your own calculator.
|
||||
</p>
|
||||
<p>The command line <i>Convert</i> utility delivered with the Emu48
|
||||
program package was originally designed to convert HP48 ROM images
|
||||
files from one of the various used ROM image formats of the 90s to
|
||||
the unpacked format originally used by Emu48. The 2nd important
|
||||
task of this tool is updating the I/O register area with zeros.
|
||||
Most images had been created with a ROM upload program where the
|
||||
I/O register area was mapped over the ROM content and so the ROM
|
||||
image file contain a wrong content at this position. Executing the
|
||||
selftest on a HP38 or a HP48 will report an IROM fail then. To fix
|
||||
this the <i>Convert</i> utility overwrites the I/O register area
|
||||
in the destination file with zeros. Final notice, the convert
|
||||
utility shows the CRC result after the file convert and a passed
|
||||
ROM CRC test does <u><b>not</b></u> imply, that the source file
|
||||
is in an Emu48 suitable format!
|
||||
</p>
|
||||
<ul>
|
||||
<li>HP38
|
||||
<p>To upload the ROM of your HP38G, you will need a special aplet
|
||||
|
|
1238
KML_20.DOC
1238
KML_20.DOC
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
Known bugs and restrictions of Emu48 V1.63
|
||||
Known bugs and restrictions of Emu48 V1.64
|
||||
------------------------------------------
|
||||
|
||||
- the following I/O bits aren't emulated (incomplete)
|
||||
|
@ -47,4 +47,4 @@ Known bugs and restrictions of Emu48 V1.63
|
|||
- quitting the emulator while programming the flash isn't allowed,
|
||||
because the content of flash state machine isn't saved so far
|
||||
|
||||
09/22/20 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
09/28/21 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
|
|
|
@ -1,3 +1,55 @@
|
|||
Service Pack 64 for Emu48 Version 1.0
|
||||
|
||||
DEBUGGER.C
|
||||
- bugfix in function EnterBreakpoint(), returned an uninitialized
|
||||
address value on empty breakpoint edit control
|
||||
- bugfix in function OnDrawBreakWnd(), fixed highlighted background
|
||||
color
|
||||
|
||||
DISASM.C
|
||||
- bugfix in function disasm_1() and disasm_8(), fixed decoding of
|
||||
r=ss, ss=r and rssEX with ss = 5, 6, 7, D, E or F register select
|
||||
|
||||
EMU48.C
|
||||
- changed function OnContextMenu(), when the context menu was
|
||||
generated from the keyboard it opened at a fix position, now when
|
||||
the mouse cursor position is inside the client window, at the
|
||||
mouse cursor position
|
||||
|
||||
EMU48.RC
|
||||
- changed version and copyright
|
||||
|
||||
ENGINE.C
|
||||
- changed function InitAdjustSpeed(), added critical section for
|
||||
writing reference CPU cycles and reference time
|
||||
- bugfix in function AdjKeySpeed() and SetSpeed(), removed critical
|
||||
section handling for initializing CPU slow down, because this
|
||||
section is locked when the CPU emulation thread already slow down
|
||||
the CPU speed
|
||||
|
||||
FETCH.C
|
||||
- bugfix in table o81Af2_, o81Af1_ and o81Af0_, replaced o_invalid6
|
||||
function pointers by their corresponding opcode function
|
||||
- bugfix in table o12_, o11_ and o10_, replaced o_invalid3 function
|
||||
pointers by their corresponding opcode function
|
||||
|
||||
LODEPNG.C
|
||||
- changed implementation file to LodePNG version 20210627 with
|
||||
unmarked typecast patches for x64 compatibility, Copyright (c)
|
||||
2005-2021 Lode Vandevenne
|
||||
|
||||
LODEPNG.H
|
||||
- changed header file to LodePNG version 20210627
|
||||
|
||||
MOPS.C
|
||||
- bugfix in function ReadT2Acc(), moved critical section because
|
||||
InitAdjustSpeed() part is already protected
|
||||
|
||||
SOUND.C
|
||||
- bugfix in function SoundOut(), removed critical section handling
|
||||
because InitAdjustSpeed() is already protected
|
||||
|
||||
|
||||
Service Pack 63 for Emu48 Version 1.0
|
||||
|
||||
DISPLAY.C
|
||||
|
|
|
@ -2893,8 +2893,6 @@ static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam,
|
|||
{
|
||||
static BP_T *sBp;
|
||||
|
||||
DWORD dwAddr;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
|
@ -2913,9 +2911,8 @@ static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam,
|
|||
case IDC_BPREAD: sBp->nType = BP_READ; return TRUE;
|
||||
case IDC_BPWRITE: sBp->nType = BP_WRITE; return TRUE;
|
||||
case IDOK:
|
||||
if (!GetAddr(hDlg,IDC_ENTERADR,&dwAddr,0xFFFFF,disassembler_symb))
|
||||
if (!GetAddr(hDlg,IDC_ENTERADR,&sBp->dwAddr,0xFFFFF,disassembler_symb))
|
||||
return FALSE;
|
||||
sBp->dwAddr = dwAddr;
|
||||
// no break
|
||||
case IDCANCEL:
|
||||
EndDialog(hDlg,wParam);
|
||||
|
@ -2947,42 +2944,35 @@ static __inline BOOL OnDrawBreakWnd(LPDRAWITEMSTRUCT lpdis)
|
|||
COLORREF crBkColor,crTextColor;
|
||||
HDC hdcMem;
|
||||
HBITMAP hBmpOld;
|
||||
INT i;
|
||||
|
||||
if (lpdis->itemID == -1) // no item in list box
|
||||
return TRUE;
|
||||
|
||||
crBkColor = GetBkColor(lpdis->hDC); // save actual color settings
|
||||
crTextColor = GetTextColor(lpdis->hDC);
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED) // cursor line
|
||||
{
|
||||
crBkColor = COLOR_NAVY;
|
||||
crTextColor = COLOR_WHITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
crBkColor = COLOR_WHITE;
|
||||
crTextColor = COLOR_BLACK;
|
||||
SetBkColor(lpdis->hDC,GetSysColor(COLOR_HIGHLIGHT));
|
||||
SetTextColor(lpdis->hDC,GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
}
|
||||
|
||||
// write Text
|
||||
crBkColor = SetBkColor(lpdis->hDC,crBkColor);
|
||||
crTextColor = SetTextColor(lpdis->hDC,crTextColor);
|
||||
|
||||
SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LPARAM) szBuf);
|
||||
ExtTextOut(lpdis->hDC,(int)(lpdis->rcItem.left)+17,(int)(lpdis->rcItem.top),
|
||||
ETO_OPAQUE,(LPRECT)&lpdis->rcItem,szBuf,lstrlen(szBuf),NULL);
|
||||
|
||||
SetBkColor(lpdis->hDC,crBkColor);
|
||||
SetBkColor(lpdis->hDC,crBkColor); // restore color settings
|
||||
SetTextColor(lpdis->hDC,crTextColor);
|
||||
|
||||
// draw checkbox
|
||||
i = (INT) SendMessage(lpdis->hwndItem,LB_GETITEMDATA,lpdis->itemID,0);
|
||||
hdcMem = CreateCompatibleDC(lpdis->hDC);
|
||||
_ASSERT(hBmpCheckBox);
|
||||
hBmpOld = (HBITMAP) SelectObject(hdcMem,hBmpCheckBox);
|
||||
|
||||
BitBlt(lpdis->hDC,lpdis->rcItem.left+2,lpdis->rcItem.top+2,
|
||||
11,lpdis->rcItem.bottom - lpdis->rcItem.top,
|
||||
hdcMem,sBreakpoint[i].bEnable ? 0 : 10,0,SRCCOPY);
|
||||
hdcMem,sBreakpoint[lpdis->itemData].bEnable ? 0 : 10,0,SRCCOPY);
|
||||
|
||||
SelectObject(hdcMem,hBmpOld);
|
||||
DeleteDC(hdcMem);
|
||||
|
|
|
@ -425,8 +425,8 @@ static LPTSTR disasm_1 (DWORD *addr, LPTSTR out)
|
|||
fn = read_nibble (addr);
|
||||
c = (fn < 8); // flag for operand register
|
||||
fn = (fn & 7); // get register number
|
||||
if (fn > 4) // illegal opcode
|
||||
break; // no output
|
||||
if (fn > 4) // unsupported opcode
|
||||
fn -= 4; // map to valid scratch register
|
||||
switch (disassembler_mode)
|
||||
{
|
||||
case HP_MNEMONICS:
|
||||
|
@ -457,8 +457,8 @@ static LPTSTR disasm_1 (DWORD *addr, LPTSTR out)
|
|||
fn = read_nibble (addr);
|
||||
c = (fn < 8); // flag for operand register
|
||||
fn = (fn & 7); // get register number
|
||||
if (fn > 4) // illegal opcode
|
||||
break; // no output
|
||||
if (fn > 4) // unsupported opcode
|
||||
fn -= 4; // map to valid scratch register
|
||||
switch (disassembler_mode)
|
||||
{
|
||||
case HP_MNEMONICS:
|
||||
|
@ -680,6 +680,7 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out)
|
|||
{
|
||||
BYTE n;
|
||||
BYTE fn;
|
||||
BYTE rn;
|
||||
LPTSTR p = out;
|
||||
TCHAR c;
|
||||
TCHAR buf[20];
|
||||
|
@ -975,48 +976,49 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out)
|
|||
if (n > 2) // illegal opcode
|
||||
break; // no output
|
||||
c = (TCHAR) read_nibble (addr);
|
||||
if (((int) c & 7) > 4) // illegal opcode
|
||||
break; // no output
|
||||
rn = (c & 7); // get register number
|
||||
c = (c < 8); // flag for operand register
|
||||
if (rn > 4) // unsupported opcode
|
||||
rn -= 4; // map to valid scratch register
|
||||
switch (disassembler_mode)
|
||||
{
|
||||
case HP_MNEMONICS:
|
||||
c = (TCHAR) (c ? _T('A') : _T('C'));
|
||||
if (n == 2)
|
||||
{
|
||||
wsprintf (buf, _T("%cR%dEX.F"), ((int) c < 8) ? _T('A') : _T('C'),
|
||||
(int) c & 7);
|
||||
wsprintf (buf, _T("%cR%dEX.F"), c, rn);
|
||||
}
|
||||
else
|
||||
if (n == 1)
|
||||
{
|
||||
wsprintf (buf, _T("%c=R%d.F"), ((int) c < 8) ? _T('A') : _T('C'),
|
||||
(int) c & 7);
|
||||
wsprintf (buf, _T("%c=R%d.F"), c, rn);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf (buf, _T("R%d=%c.F"), (int) c & 7,
|
||||
((int) c < 8) ? _T('A') : _T('C'));
|
||||
wsprintf (buf, _T("R%d=%c.F"), rn, c);
|
||||
}
|
||||
p = append_str (out, buf);
|
||||
p = append_tab (out);
|
||||
p = append_field (p, fn);
|
||||
break;
|
||||
case CLASS_MNEMONICS:
|
||||
c = (TCHAR) (c ? _T('a') : _T('c'));
|
||||
p = append_str (out, (n == 2) ? _T("exg") : _T("move"));
|
||||
p = append_field (p, fn);
|
||||
p = append_tab (out);
|
||||
if (n == 1)
|
||||
{
|
||||
wsprintf (buf, _T("r%d"), (int) c & 7);
|
||||
wsprintf (buf, _T("r%d"), rn);
|
||||
p = append_str (p, buf);
|
||||
}
|
||||
else
|
||||
p = append_str (p, ((int) c < 8) ? _T("a") : _T("c"));
|
||||
*p++ = c;
|
||||
p = append_str (p, _T(", "));
|
||||
if (n == 1)
|
||||
p = append_str (p, ((int) c < 8) ? _T("a") : _T("c"));
|
||||
*p++ = c;
|
||||
else
|
||||
{
|
||||
wsprintf (buf, _T("r%d"), (int) c & 7);
|
||||
wsprintf (buf, _T("r%d"), rn);
|
||||
p = append_str (p, buf);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "kml.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#define VERSION "1.63"
|
||||
#define VERSION "1.64"
|
||||
|
||||
#ifdef _DEBUG
|
||||
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");
|
||||
|
@ -1742,26 +1742,40 @@ static LRESULT OnAbout(VOID)
|
|||
|
||||
static VOID OnContextMenu(LPARAM lParam)
|
||||
{
|
||||
HMENU hMenu;
|
||||
POINT pt,ptc;
|
||||
|
||||
if (GetMenu(hWnd) == NULL) // no main window menu
|
||||
{
|
||||
BOOL bContextMenu = TRUE; // call context menu
|
||||
POINT pt;
|
||||
|
||||
POINTSTOPOINT(pt,MAKEPOINTS(lParam)); // mouse position
|
||||
|
||||
if (pt.x == -1 && pt.y == -1) // VK_APPS
|
||||
{
|
||||
pt.x = 15; // open context help at client position 15,15
|
||||
pt.y = 15;
|
||||
VERIFY(ClientToScreen(hWnd,&pt));
|
||||
RECT rc;
|
||||
|
||||
GetCursorPos(&pt); // get current mouse position
|
||||
GetWindowRect(hWnd,&rc); // get position of active window
|
||||
if (PtInRect(&rc,pt)==FALSE) // mouse position outside active window
|
||||
{
|
||||
pt.x = 15; // open context help at client position 15,15
|
||||
pt.y = 15;
|
||||
VERIFY(ClientToScreen(hWnd,&pt));
|
||||
}
|
||||
}
|
||||
else // got a mouse position
|
||||
{
|
||||
POINT ptc = pt;
|
||||
// convert mouse into client position
|
||||
VERIFY(ScreenToClient(hWnd,&ptc));
|
||||
|
||||
// in client area not over a button
|
||||
bContextMenu = (ptc.y >= 0 && !MouseIsButton(ptc.x,ptc.y));
|
||||
}
|
||||
|
||||
ptc = pt;
|
||||
VERIFY(ScreenToClient(hWnd,&ptc)); // convert mouse into client position
|
||||
|
||||
// in client area not over a button
|
||||
if (ptc.y >= 0 && !MouseIsButton(ptc.x,ptc.y))
|
||||
if (bContextMenu) // call the context menu
|
||||
{
|
||||
HMENU hMenu;
|
||||
|
||||
// load the popup menu resource
|
||||
if ((hMenu = LoadMenu(hApp,MAKEINTRESOURCE(IDM_MENU))) != NULL)
|
||||
{
|
||||
|
|
|
@ -303,7 +303,7 @@ FONT 8, "MS Sans Serif"
|
|||
BEGIN
|
||||
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
|
||||
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
|
||||
LTEXT "Copyright © 2020 Christoph Gießelink && Sébastien Carlier",
|
||||
LTEXT "Copyright © 2021 Christoph Gießelink && Sébastien Carlier",
|
||||
IDC_STATIC,29,18,181,8
|
||||
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
|
||||
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
|
||||
|
@ -723,8 +723,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,6,3,0
|
||||
PRODUCTVERSION 1,6,3,0
|
||||
FILEVERSION 1,6,4,0
|
||||
PRODUCTVERSION 1,6,4,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -741,12 +741,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 6, 3, 0\0"
|
||||
VALUE "FileVersion", "1, 6, 4, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2020\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2021\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 6, 3, 0\0"
|
||||
VALUE "ProductVersion", "1, 6, 4, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -343,10 +343,15 @@ VOID InitAdjustSpeed(VOID)
|
|||
if (!bEnableSlow || (!bCpuSlow && !bKeySlow && !bSoundSlow && nOpcSlow == 0))
|
||||
{
|
||||
LARGE_INTEGER lTime; // sample timer ticks
|
||||
// save reference cycles
|
||||
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
|
||||
QueryPerformanceCounter(&lTime); // get timer ticks
|
||||
dwSpeedRef = lTime.LowPart; // save reference time
|
||||
|
||||
EnterCriticalSection(&csSlowLock);
|
||||
{
|
||||
// save reference cycles
|
||||
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
|
||||
QueryPerformanceCounter(&lTime);// get timer ticks
|
||||
dwSpeedRef = lTime.LowPart; // save reference time
|
||||
}
|
||||
LeaveCriticalSection(&csSlowLock);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -360,29 +365,21 @@ VOID AdjKeySpeed(VOID) // slow down key repeat
|
|||
for (i = 0;i < ARRAYSIZEOF(Chipset.Keyboard_Row) && !bKey;++i)
|
||||
bKey = (Chipset.Keyboard_Row[i] != 0);
|
||||
|
||||
EnterCriticalSection(&csSlowLock);
|
||||
if (bKey) // key pressed
|
||||
{
|
||||
if (bKey) // key pressed
|
||||
{
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
}
|
||||
bKeySlow = bKey; // save new state
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
}
|
||||
LeaveCriticalSection(&csSlowLock);
|
||||
bKeySlow = bKey; // save new state
|
||||
return;
|
||||
}
|
||||
|
||||
VOID SetSpeed(BOOL bAdjust) // set emulation speed
|
||||
{
|
||||
EnterCriticalSection(&csSlowLock);
|
||||
if (bAdjust) // switch to real speed
|
||||
{
|
||||
if (bAdjust) // switch to real speed
|
||||
{
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
}
|
||||
bCpuSlow = bAdjust; // save emulation speed
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
}
|
||||
LeaveCriticalSection(&csSlowLock);
|
||||
bCpuSlow = bAdjust; // save emulation speed
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
99
Sources/Emu48/EXTERNAL.C
Normal file
99
Sources/Emu48/EXTERNAL.C
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* external.c
|
||||
*
|
||||
* This file is part of Emu48
|
||||
*
|
||||
* Copyright (C) 1995 Sebastien Carlier
|
||||
* Copyright (C) 2005 Christoph Gießelink
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
#include "Emu48.h"
|
||||
#include "ops.h"
|
||||
|
||||
//| 38G | 39G | 40G | 48SX | 48GX | 49G | Name
|
||||
//#F0E4F #80F0F #80F0F #706D2 #80850 #80F0F =SFLAG53_56
|
||||
|
||||
// memory address for flags -53 to -56
|
||||
#define SFLAG53_56 ( (cCurrentRomType=='6') \
|
||||
? 0xE0E4F \
|
||||
: ( (cCurrentRomType=='A') \
|
||||
? 0xF0E4F \
|
||||
: ( (cCurrentRomType!='E' && cCurrentRomType!='X') \
|
||||
? ( (cCurrentRomType=='S') \
|
||||
? 0x706D2 \
|
||||
: 0x80850 \
|
||||
) \
|
||||
: 0x80F0F \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
VOID External(CHIPSET* w) // Beep patch
|
||||
{
|
||||
BYTE fbeep;
|
||||
DWORD freq,dur;
|
||||
|
||||
freq = Npack(w->D,5); // frequency in Hz
|
||||
dur = Npack(w->C,5); // duration in ms
|
||||
Nread(&fbeep,SFLAG53_56,1); // fetch system flags -53 to -56
|
||||
|
||||
w->carry = TRUE; // setting of no beep
|
||||
if (!(fbeep & 0x8) && freq) // bit -56 clear and frequency > 0 Hz
|
||||
{
|
||||
if (freq > 4400) freq = 4400; // high limit of HP (SX)
|
||||
|
||||
SoundBeep(freq,dur); // beeping
|
||||
|
||||
// estimate cpu cycles for beeping time (2MHz / 4MHz)
|
||||
w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
|
||||
|
||||
// original routine return with...
|
||||
w->P = 0; // P=0
|
||||
w->intk = TRUE; // INTON
|
||||
w->carry = FALSE; // RTNCC
|
||||
}
|
||||
w->pc = rstkpop();
|
||||
return;
|
||||
}
|
||||
|
||||
VOID RCKBp(CHIPSET* w) // ROM Check Beep patch
|
||||
{
|
||||
DWORD dw2F,dwCpuFreq;
|
||||
DWORD freq,dur;
|
||||
BYTE f,d;
|
||||
|
||||
f = w->C[1]; // f = freq ctl
|
||||
d = w->C[0]; // d = duration ctl
|
||||
|
||||
if (cCurrentRomType == 'S') // Clarke chip with 48S ROM
|
||||
{
|
||||
// CPU strobe frequency @ RATE 14 = 1.97MHz
|
||||
dwCpuFreq = ((14 + 1) * 524288) >> 2;
|
||||
|
||||
dw2F = f * 126 + 262; // F=f*63+131
|
||||
}
|
||||
else // York chip with 48G and later ROM
|
||||
{
|
||||
// CPU strobe frequency @ RATE 27 = 3.67MHz
|
||||
// CPU strobe frequency @ RATE 29 = 3.93MHz
|
||||
dwCpuFreq = ((27 + 1) * 524288) >> 2;
|
||||
|
||||
dw2F = f * 180 + 367; // F=f*90+183.5
|
||||
}
|
||||
|
||||
freq = dwCpuFreq / dw2F;
|
||||
dur = (dw2F * (256 - 16 * d)) * 1000 / 2 / dwCpuFreq;
|
||||
|
||||
if (freq > 4400) freq = 4400; // high limit of HP
|
||||
|
||||
SoundBeep(freq,dur); // beeping
|
||||
|
||||
// estimate cpu cycles for beeping time (2MHz / 4MHz)
|
||||
w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
|
||||
|
||||
w->P = 0; // P=0
|
||||
w->carry = FALSE; // RTNCC
|
||||
w->pc = rstkpop();
|
||||
return;
|
||||
}
|
|
@ -345,17 +345,17 @@ static JMPTAB o81Af2_[] =
|
|||
(LPCVOID) o81Af22, F,
|
||||
(LPCVOID) o81Af23, F,
|
||||
(LPCVOID) o81Af24, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o81Af21, F,
|
||||
(LPCVOID) o81Af22, F,
|
||||
(LPCVOID) o81Af23, F,
|
||||
(LPCVOID) o81Af28, F,
|
||||
(LPCVOID) o81Af29, F,
|
||||
(LPCVOID) o81Af2A, F,
|
||||
(LPCVOID) o81Af2B, F,
|
||||
(LPCVOID) o81Af2C, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F
|
||||
(LPCVOID) o81Af29, F,
|
||||
(LPCVOID) o81Af2A, F,
|
||||
(LPCVOID) o81Af2B, F
|
||||
};
|
||||
|
||||
static JMPTAB o81Af1_[] =
|
||||
|
@ -365,17 +365,17 @@ static JMPTAB o81Af1_[] =
|
|||
(LPCVOID) o81Af12, F,
|
||||
(LPCVOID) o81Af13, F,
|
||||
(LPCVOID) o81Af14, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o81Af11, F,
|
||||
(LPCVOID) o81Af12, F,
|
||||
(LPCVOID) o81Af13, F,
|
||||
(LPCVOID) o81Af18, F,
|
||||
(LPCVOID) o81Af19, F,
|
||||
(LPCVOID) o81Af1A, F,
|
||||
(LPCVOID) o81Af1B, F,
|
||||
(LPCVOID) o81Af1C, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F
|
||||
(LPCVOID) o81Af19, F,
|
||||
(LPCVOID) o81Af1A, F,
|
||||
(LPCVOID) o81Af1B, F
|
||||
};
|
||||
|
||||
static JMPTAB o81Af0_[] =
|
||||
|
@ -385,17 +385,17 @@ static JMPTAB o81Af0_[] =
|
|||
(LPCVOID) o81Af02, F,
|
||||
(LPCVOID) o81Af03, F,
|
||||
(LPCVOID) o81Af04, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o81Af01, F,
|
||||
(LPCVOID) o81Af02, F,
|
||||
(LPCVOID) o81Af03, F,
|
||||
(LPCVOID) o81Af08, F,
|
||||
(LPCVOID) o81Af09, F,
|
||||
(LPCVOID) o81Af0A, F,
|
||||
(LPCVOID) o81Af0B, F,
|
||||
(LPCVOID) o81Af0C, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F,
|
||||
(LPCVOID) o_invalid6, F
|
||||
(LPCVOID) o81Af09, F,
|
||||
(LPCVOID) o81Af0A, F,
|
||||
(LPCVOID) o81Af0B, F
|
||||
};
|
||||
|
||||
static JMPTAB o81A_[] =
|
||||
|
@ -625,17 +625,17 @@ static JMPTAB o12_[] =
|
|||
(LPCVOID) o122, F,
|
||||
(LPCVOID) o123, F,
|
||||
(LPCVOID) o124, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o121, F,
|
||||
(LPCVOID) o122, F,
|
||||
(LPCVOID) o123, F,
|
||||
(LPCVOID) o128, F,
|
||||
(LPCVOID) o129, F,
|
||||
(LPCVOID) o12A, F,
|
||||
(LPCVOID) o12B, F,
|
||||
(LPCVOID) o12C, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F
|
||||
(LPCVOID) o129, F,
|
||||
(LPCVOID) o12A, F,
|
||||
(LPCVOID) o12B, F
|
||||
};
|
||||
|
||||
static JMPTAB o11_[] =
|
||||
|
@ -645,17 +645,17 @@ static JMPTAB o11_[] =
|
|||
(LPCVOID) o112, F,
|
||||
(LPCVOID) o113, F,
|
||||
(LPCVOID) o114, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o111, F,
|
||||
(LPCVOID) o112, F,
|
||||
(LPCVOID) o113, F,
|
||||
(LPCVOID) o118, F,
|
||||
(LPCVOID) o119, F,
|
||||
(LPCVOID) o11A, F,
|
||||
(LPCVOID) o11B, F,
|
||||
(LPCVOID) o11C, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F
|
||||
(LPCVOID) o119, F,
|
||||
(LPCVOID) o11A, F,
|
||||
(LPCVOID) o11B, F
|
||||
};
|
||||
|
||||
static JMPTAB o10_[] =
|
||||
|
@ -665,17 +665,17 @@ static JMPTAB o10_[] =
|
|||
(LPCVOID) o102, F,
|
||||
(LPCVOID) o103, F,
|
||||
(LPCVOID) o104, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o101, F,
|
||||
(LPCVOID) o102, F,
|
||||
(LPCVOID) o103, F,
|
||||
(LPCVOID) o108, F,
|
||||
(LPCVOID) o109, F,
|
||||
(LPCVOID) o10A, F,
|
||||
(LPCVOID) o10B, F,
|
||||
(LPCVOID) o10C, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F,
|
||||
(LPCVOID) o_invalid3, F
|
||||
(LPCVOID) o109, F,
|
||||
(LPCVOID) o10A, F,
|
||||
(LPCVOID) o10B, F
|
||||
};
|
||||
|
||||
static JMPTAB o1_[] =
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
LodePNG version 20200306
|
||||
LodePNG version 20210627
|
||||
|
||||
Copyright (c) 2005-2020 Lode Vandevenne
|
||||
Copyright (c) 2005-2021 Lode Vandevenne
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -44,7 +44,7 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for
|
|||
#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/
|
||||
#endif /*_MSC_VER */
|
||||
|
||||
const char* LODEPNG_VERSION_STRING = "20200306";
|
||||
const char* LODEPNG_VERSION_STRING = "20210627";
|
||||
|
||||
/*
|
||||
This source file is built up in the following large parts. The code sections
|
||||
|
@ -299,6 +299,7 @@ static void string_cleanup(char** out) {
|
|||
*out = NULL;
|
||||
}
|
||||
|
||||
/*also appends null termination character*/
|
||||
static char* alloc_string_sized(const char* in, size_t insize) {
|
||||
char* out = (char*)lodepng_malloc(insize + 1);
|
||||
if(out) {
|
||||
|
@ -1260,7 +1261,7 @@ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d,
|
|||
|
||||
/*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/
|
||||
static unsigned inflateHuffmanBlock(ucvector* out, LodePNGBitReader* reader,
|
||||
unsigned btype) {
|
||||
unsigned btype, size_t max_output_size) {
|
||||
unsigned error = 0;
|
||||
HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/
|
||||
HuffmanTree tree_d; /*the huffman tree for distance codes*/
|
||||
|
@ -1341,6 +1342,9 @@ static unsigned inflateHuffmanBlock(ucvector* out, LodePNGBitReader* reader,
|
|||
/* TODO: revise error codes 10,11,50: the above comment is no longer valid */
|
||||
ERROR_BREAK(51); /*error, bit pointer jumps past memory*/
|
||||
}
|
||||
if(max_output_size && out->size > max_output_size) {
|
||||
ERROR_BREAK(109); /*error, larger than max size*/
|
||||
}
|
||||
}
|
||||
|
||||
HuffmanTree_cleanup(&tree_ll);
|
||||
|
@ -1398,9 +1402,9 @@ static unsigned lodepng_inflatev(ucvector* out,
|
|||
|
||||
if(BTYPE == 3) return 20; /*error: invalid BTYPE*/
|
||||
else if(BTYPE == 0) error = inflateNoCompression(out, &reader, settings); /*no compression*/
|
||||
else error = inflateHuffmanBlock(out, &reader, BTYPE); /*compression, BTYPE 01 or 10*/
|
||||
|
||||
if(error) return error;
|
||||
else error = inflateHuffmanBlock(out, &reader, BTYPE, settings->max_output_size); /*compression, BTYPE 01 or 10*/
|
||||
if(!error && settings->max_output_size && out->size > settings->max_output_size) error = 109;
|
||||
if(error) break;
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -1421,6 +1425,12 @@ static unsigned inflatev(ucvector* out, const unsigned char* in, size_t insize,
|
|||
if(settings->custom_inflate) {
|
||||
unsigned error = settings->custom_inflate(&out->data, &out->size, in, insize, settings);
|
||||
out->allocsize = out->size;
|
||||
if(error) {
|
||||
/*the custom inflate is allowed to have its own error codes, however, we translate it to code 110*/
|
||||
error = 110;
|
||||
/*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/
|
||||
if(settings->max_output_size && out->size > settings->max_output_size) error = 109;
|
||||
}
|
||||
return error;
|
||||
} else {
|
||||
return lodepng_inflatev(out, in, insize, settings);
|
||||
|
@ -2116,7 +2126,9 @@ static unsigned deflate(unsigned char** out, size_t* outsize,
|
|||
const unsigned char* in, size_t insize,
|
||||
const LodePNGCompressSettings* settings) {
|
||||
if(settings->custom_deflate) {
|
||||
return settings->custom_deflate(out, outsize, in, insize, settings);
|
||||
unsigned error = settings->custom_deflate(out, outsize, in, insize, settings);
|
||||
/*the custom deflate is allowed to have its own error codes, however, we translate it to code 111*/
|
||||
return error ? 111 : 0;
|
||||
} else {
|
||||
return lodepng_deflate(out, outsize, in, insize, settings);
|
||||
}
|
||||
|
@ -2213,10 +2225,16 @@ unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const uns
|
|||
/*expected_size is expected output size, to avoid intermediate allocations. Set to 0 if not known. */
|
||||
static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t expected_size,
|
||||
const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) {
|
||||
unsigned error;
|
||||
if(settings->custom_zlib) {
|
||||
return settings->custom_zlib(out, outsize, in, insize, settings);
|
||||
error = settings->custom_zlib(out, outsize, in, insize, settings);
|
||||
if(error) {
|
||||
/*the custom zlib is allowed to have its own error codes, however, we translate it to code 110*/
|
||||
error = 110;
|
||||
/*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/
|
||||
if(settings->max_output_size && *outsize > settings->max_output_size) error = 109;
|
||||
}
|
||||
} else {
|
||||
unsigned error;
|
||||
ucvector v = ucvector_init(*out, *outsize);
|
||||
if(expected_size) {
|
||||
/*reserve the memory to avoid intermediate reallocations*/
|
||||
|
@ -2226,8 +2244,8 @@ static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t exp
|
|||
error = lodepng_zlib_decompressv(&v, in, insize, settings);
|
||||
*out = v.data;
|
||||
*outsize = v.size;
|
||||
return error;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
@ -2275,7 +2293,9 @@ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsig
|
|||
static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
|
||||
size_t insize, const LodePNGCompressSettings* settings) {
|
||||
if(settings->custom_zlib) {
|
||||
return settings->custom_zlib(out, outsize, in, insize, settings);
|
||||
unsigned error = settings->custom_zlib(out, outsize, in, insize, settings);
|
||||
/*the custom zlib is allowed to have its own error codes, however, we translate it to code 111*/
|
||||
return error ? 111 : 0;
|
||||
} else {
|
||||
return lodepng_zlib_compress(out, outsize, in, insize, settings);
|
||||
}
|
||||
|
@ -2334,13 +2354,14 @@ const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT
|
|||
void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) {
|
||||
settings->ignore_adler32 = 0;
|
||||
settings->ignore_nlen = 0;
|
||||
settings->max_output_size = 0;
|
||||
|
||||
settings->custom_zlib = 0;
|
||||
settings->custom_inflate = 0;
|
||||
settings->custom_context = 0;
|
||||
}
|
||||
|
||||
const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0, 0};
|
||||
const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
|
@ -2872,8 +2893,8 @@ static void LodePNGText_cleanup(LodePNGInfo* info) {
|
|||
|
||||
static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) {
|
||||
size_t i = 0;
|
||||
dest->text_keys = 0;
|
||||
dest->text_strings = 0;
|
||||
dest->text_keys = NULL;
|
||||
dest->text_strings = NULL;
|
||||
dest->text_num = 0;
|
||||
for(i = 0; i != source->text_num; ++i) {
|
||||
CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i]));
|
||||
|
@ -2932,10 +2953,10 @@ static void LodePNGIText_cleanup(LodePNGInfo* info) {
|
|||
|
||||
static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) {
|
||||
size_t i = 0;
|
||||
dest->itext_keys = 0;
|
||||
dest->itext_langtags = 0;
|
||||
dest->itext_transkeys = 0;
|
||||
dest->itext_strings = 0;
|
||||
dest->itext_keys = NULL;
|
||||
dest->itext_langtags = NULL;
|
||||
dest->itext_transkeys = NULL;
|
||||
dest->itext_strings = NULL;
|
||||
dest->itext_num = 0;
|
||||
for(i = 0; i != source->itext_num; ++i) {
|
||||
CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i],
|
||||
|
@ -4093,10 +4114,12 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
|
|||
case 0:
|
||||
for(i = 0; i != length; ++i) recon[i] = scanline[i];
|
||||
break;
|
||||
case 1:
|
||||
case 1: {
|
||||
size_t j = 0;
|
||||
for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
|
||||
for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth];
|
||||
for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + recon[j];
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
if(precon) {
|
||||
for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
|
||||
|
@ -4106,24 +4129,56 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
|
|||
break;
|
||||
case 3:
|
||||
if(precon) {
|
||||
size_t j = 0;
|
||||
for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u);
|
||||
for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u);
|
||||
/* Unroll independent paths of this predictor. A 6x and 8x version is also possible but that adds
|
||||
too much code. Whether this speeds up anything depends on compiler and settings. */
|
||||
if(bytewidth >= 4) {
|
||||
for(; i + 3 < length; i += 4, j += 4) {
|
||||
unsigned char s0 = scanline[i + 0], r0 = recon[j + 0], p0 = precon[i + 0];
|
||||
unsigned char s1 = scanline[i + 1], r1 = recon[j + 1], p1 = precon[i + 1];
|
||||
unsigned char s2 = scanline[i + 2], r2 = recon[j + 2], p2 = precon[i + 2];
|
||||
unsigned char s3 = scanline[i + 3], r3 = recon[j + 3], p3 = precon[i + 3];
|
||||
recon[i + 0] = s0 + ((r0 + p0) >> 1u);
|
||||
recon[i + 1] = s1 + ((r1 + p1) >> 1u);
|
||||
recon[i + 2] = s2 + ((r2 + p2) >> 1u);
|
||||
recon[i + 3] = s3 + ((r3 + p3) >> 1u);
|
||||
}
|
||||
} else if(bytewidth >= 3) {
|
||||
for(; i + 2 < length; i += 3, j += 3) {
|
||||
unsigned char s0 = scanline[i + 0], r0 = recon[j + 0], p0 = precon[i + 0];
|
||||
unsigned char s1 = scanline[i + 1], r1 = recon[j + 1], p1 = precon[i + 1];
|
||||
unsigned char s2 = scanline[i + 2], r2 = recon[j + 2], p2 = precon[i + 2];
|
||||
recon[i + 0] = s0 + ((r0 + p0) >> 1u);
|
||||
recon[i + 1] = s1 + ((r1 + p1) >> 1u);
|
||||
recon[i + 2] = s2 + ((r2 + p2) >> 1u);
|
||||
}
|
||||
} else if(bytewidth >= 2) {
|
||||
for(; i + 1 < length; i += 2, j += 2) {
|
||||
unsigned char s0 = scanline[i + 0], r0 = recon[j + 0], p0 = precon[i + 0];
|
||||
unsigned char s1 = scanline[i + 1], r1 = recon[j + 1], p1 = precon[i + 1];
|
||||
recon[i + 0] = s0 + ((r0 + p0) >> 1u);
|
||||
recon[i + 1] = s1 + ((r1 + p1) >> 1u);
|
||||
}
|
||||
}
|
||||
for(; i != length; ++i, ++j) recon[i] = scanline[i] + ((recon[j] + precon[i]) >> 1u);
|
||||
} else {
|
||||
size_t j = 0;
|
||||
for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
|
||||
for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u);
|
||||
for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + (recon[j] >> 1u);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(precon) {
|
||||
size_t j = 0;
|
||||
for(i = 0; i != bytewidth; ++i) {
|
||||
recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
|
||||
}
|
||||
|
||||
/* Unroll independent paths of the paeth predictor. A 6x and 8x version would also be possible but that
|
||||
adds too much code. Whether this actually speeds anything up at all depends on compiler and settings. */
|
||||
/* Unroll independent paths of the paeth predictor. A 6x and 8x version is also possible but that
|
||||
adds too much code. Whether this speeds up anything depends on compiler and settings. */
|
||||
if(bytewidth >= 4) {
|
||||
for(; i + 3 < length; i += 4) {
|
||||
size_t j = i - bytewidth;
|
||||
for(; i + 3 < length; i += 4, j += 4) {
|
||||
unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3];
|
||||
unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3];
|
||||
unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3];
|
||||
|
@ -4134,8 +4189,7 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
|
|||
recon[i + 3] = s3 + paethPredictor(r3, p3, q3);
|
||||
}
|
||||
} else if(bytewidth >= 3) {
|
||||
for(; i + 2 < length; i += 3) {
|
||||
size_t j = i - bytewidth;
|
||||
for(; i + 2 < length; i += 3, j += 3) {
|
||||
unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2];
|
||||
unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2];
|
||||
unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2];
|
||||
|
@ -4145,8 +4199,7 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
|
|||
recon[i + 2] = s2 + paethPredictor(r2, p2, q2);
|
||||
}
|
||||
} else if(bytewidth >= 2) {
|
||||
for(; i + 1 < length; i += 2) {
|
||||
size_t j = i - bytewidth;
|
||||
for(; i + 1 < length; i += 2, j += 2) {
|
||||
unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1];
|
||||
unsigned char r0 = recon[j + 0], r1 = recon[j + 1];
|
||||
unsigned char p0 = precon[i + 0], p1 = precon[i + 1];
|
||||
|
@ -4156,16 +4209,17 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
|
|||
}
|
||||
}
|
||||
|
||||
for(; i != length; ++i) {
|
||||
recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
|
||||
for(; i != length; ++i, ++j) {
|
||||
recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[j]));
|
||||
}
|
||||
} else {
|
||||
size_t j = 0;
|
||||
for(i = 0; i != bytewidth; ++i) {
|
||||
recon[i] = scanline[i];
|
||||
}
|
||||
for(i = bytewidth; i < length; ++i) {
|
||||
for(i = bytewidth; i != length; ++i, ++j) {
|
||||
/*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/
|
||||
recon[i] = (scanline[i] + recon[i - bytewidth]);
|
||||
recon[i] = (scanline[i] + recon[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -4447,10 +4501,13 @@ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, siz
|
|||
}
|
||||
|
||||
/*compressed text chunk (zTXt)*/
|
||||
static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
|
||||
static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecoderSettings* decoder,
|
||||
const unsigned char* data, size_t chunkLength) {
|
||||
unsigned error = 0;
|
||||
|
||||
/*copy the object to change parameters in it*/
|
||||
LodePNGDecompressSettings zlibsettings = decoder->zlibsettings;
|
||||
|
||||
unsigned length, string2_begin;
|
||||
char *key = 0;
|
||||
unsigned char* str = 0;
|
||||
|
@ -4473,12 +4530,14 @@ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSetting
|
|||
if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
|
||||
|
||||
length = (unsigned)chunkLength - string2_begin;
|
||||
zlibsettings.max_output_size = decoder->max_text_size;
|
||||
/*will fail if zlib error, e.g. if length is too small*/
|
||||
error = zlib_decompress(&str, &size, 0, &data[string2_begin],
|
||||
length, zlibsettings);
|
||||
length, &zlibsettings);
|
||||
/*error: compressed text larger than decoder->max_text_size*/
|
||||
if(error && size > zlibsettings.max_output_size) error = 112;
|
||||
if(error) break;
|
||||
error = lodepng_add_text_sized(info, key, (char*)str, size);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4489,11 +4548,14 @@ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSetting
|
|||
}
|
||||
|
||||
/*international text chunk (iTXt)*/
|
||||
static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
|
||||
static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecoderSettings* decoder,
|
||||
const unsigned char* data, size_t chunkLength) {
|
||||
unsigned error = 0;
|
||||
unsigned i;
|
||||
|
||||
/*copy the object to change parameters in it*/
|
||||
LodePNGDecompressSettings zlibsettings = decoder->zlibsettings;
|
||||
|
||||
unsigned length, begin, compressed;
|
||||
char *key = 0, *langtag = 0, *transkey = 0;
|
||||
|
||||
|
@ -4550,9 +4612,12 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting
|
|||
if(compressed) {
|
||||
unsigned char* str = 0;
|
||||
size_t size = 0;
|
||||
zlibsettings.max_output_size = decoder->max_text_size;
|
||||
/*will fail if zlib error, e.g. if length is too small*/
|
||||
error = zlib_decompress(&str, &size, 0, &data[begin],
|
||||
length, zlibsettings);
|
||||
length, &zlibsettings);
|
||||
/*error: compressed text larger than decoder->max_text_size*/
|
||||
if(error && size > zlibsettings.max_output_size) error = 112;
|
||||
if(!error) error = lodepng_add_itext_sized(info, key, langtag, transkey, (char*)str, size);
|
||||
lodepng_free(str);
|
||||
} else {
|
||||
|
@ -4628,11 +4693,13 @@ static unsigned readChunk_sRGB(LodePNGInfo* info, const unsigned char* data, siz
|
|||
return 0; /* OK */
|
||||
}
|
||||
|
||||
static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
|
||||
static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecoderSettings* decoder,
|
||||
const unsigned char* data, size_t chunkLength) {
|
||||
unsigned error = 0;
|
||||
unsigned i;
|
||||
size_t size = 0;
|
||||
/*copy the object to change parameters in it*/
|
||||
LodePNGDecompressSettings zlibsettings = decoder->zlibsettings;
|
||||
|
||||
unsigned length, string2_begin;
|
||||
|
||||
|
@ -4655,9 +4722,12 @@ static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecompressSetting
|
|||
if(string2_begin > chunkLength) return 75; /*no null termination, corrupt?*/
|
||||
|
||||
length = (unsigned)chunkLength - string2_begin;
|
||||
zlibsettings.max_output_size = decoder->max_icc_size;
|
||||
error = zlib_decompress(&info->iccp_profile, &size, 0,
|
||||
&data[string2_begin],
|
||||
length, zlibsettings);
|
||||
length, &zlibsettings);
|
||||
/*error: ICC profile larger than decoder->max_icc_size*/
|
||||
if(error && size > zlibsettings.max_output_size) error = 113;
|
||||
info->iccp_profile_size = (unsigned)size;
|
||||
if(!error && !info->iccp_profile_size) error = 100; /*invalid ICC profile size*/
|
||||
return error;
|
||||
|
@ -4688,9 +4758,9 @@ unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos,
|
|||
} else if(lodepng_chunk_type_equals(chunk, "tEXt")) {
|
||||
error = readChunk_tEXt(&state->info_png, data, chunkLength);
|
||||
} else if(lodepng_chunk_type_equals(chunk, "zTXt")) {
|
||||
error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
|
||||
error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength);
|
||||
} else if(lodepng_chunk_type_equals(chunk, "iTXt")) {
|
||||
error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
|
||||
error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength);
|
||||
} else if(lodepng_chunk_type_equals(chunk, "tIME")) {
|
||||
error = readChunk_tIME(&state->info_png, data, chunkLength);
|
||||
} else if(lodepng_chunk_type_equals(chunk, "pHYs")) {
|
||||
|
@ -4702,7 +4772,7 @@ unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos,
|
|||
} else if(lodepng_chunk_type_equals(chunk, "sRGB")) {
|
||||
error = readChunk_sRGB(&state->info_png, data, chunkLength);
|
||||
} else if(lodepng_chunk_type_equals(chunk, "iCCP")) {
|
||||
error = readChunk_iCCP(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
|
||||
error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength);
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
} else {
|
||||
/* unhandled chunk is ok (is not an error) */
|
||||
|
@ -4820,13 +4890,13 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
|
|||
} else if(lodepng_chunk_type_equals(chunk, "zTXt")) {
|
||||
/*compressed text chunk (zTXt)*/
|
||||
if(state->decoder.read_text_chunks) {
|
||||
state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
|
||||
state->error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength);
|
||||
if(state->error) break;
|
||||
}
|
||||
} else if(lodepng_chunk_type_equals(chunk, "iTXt")) {
|
||||
/*international text chunk (iTXt)*/
|
||||
if(state->decoder.read_text_chunks) {
|
||||
state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
|
||||
state->error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength);
|
||||
if(state->error) break;
|
||||
}
|
||||
} else if(lodepng_chunk_type_equals(chunk, "tIME")) {
|
||||
|
@ -4845,7 +4915,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
|
|||
state->error = readChunk_sRGB(&state->info_png, data, chunkLength);
|
||||
if(state->error) break;
|
||||
} else if(lodepng_chunk_type_equals(chunk, "iCCP")) {
|
||||
state->error = readChunk_iCCP(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
|
||||
state->error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength);
|
||||
if(state->error) break;
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
} else /*it's not an implemented chunk type, so ignore it: skip over the data*/ {
|
||||
|
@ -4871,7 +4941,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
|
|||
if(!IEND) chunk = lodepng_chunk_next_const(chunk, in + insize);
|
||||
}
|
||||
|
||||
if(state->info_png.color.colortype == LCT_PALETTE && !state->info_png.color.palette) {
|
||||
if(!state->error && state->info_png.color.colortype == LCT_PALETTE && !state->info_png.color.palette) {
|
||||
state->error = 106; /* error: PNG file must have PLTE chunk if color type is palette */
|
||||
}
|
||||
|
||||
|
@ -4955,6 +5025,11 @@ unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, co
|
|||
lodepng_state_init(&state);
|
||||
state.info_raw.colortype = colortype;
|
||||
state.info_raw.bitdepth = bitdepth;
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
/*disable reading things that this function doesn't output*/
|
||||
state.decoder.read_text_chunks = 0;
|
||||
state.decoder.remember_unknown_chunks = 0;
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
error = lodepng_decode(out, w, h, &state, in, insize);
|
||||
lodepng_state_cleanup(&state);
|
||||
return error;
|
||||
|
@ -4997,6 +5072,8 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) {
|
|||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
settings->read_text_chunks = 1;
|
||||
settings->remember_unknown_chunks = 0;
|
||||
settings->max_text_size = 16777216;
|
||||
settings->max_icc_size = 16777216; /* 16MB is much more than enough for any reasonable ICC profile */
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
settings->ignore_crc = 0;
|
||||
settings->ignore_critical = 0;
|
||||
|
@ -6204,6 +6281,16 @@ const char* lodepng_error_text(unsigned code) {
|
|||
case 106: return "PNG file must have PLTE chunk if color type is palette";
|
||||
case 107: return "color convert from palette mode requested without setting the palette data in it";
|
||||
case 108: return "tried to add more than 256 values to a palette";
|
||||
/*this limit can be configured in LodePNGDecompressSettings*/
|
||||
case 109: return "tried to decompress zlib or deflate data larger than desired max_output_size";
|
||||
case 110: return "custom zlib or inflate decompression failed";
|
||||
case 111: return "custom zlib or deflate compression failed";
|
||||
/*max text size limit can be configured in LodePNGDecoderSettings. This error prevents
|
||||
unreasonable memory consumption when decoding due to impossibly large text sizes.*/
|
||||
case 112: return "compressed text unreasonably large";
|
||||
/*max ICC size limit can be configured in LodePNGDecoderSettings. This error prevents
|
||||
unreasonable memory consumption when decoding due to impossibly large ICC profile*/
|
||||
case 113: return "ICC profile unreasonably large";
|
||||
}
|
||||
return "unknown error code";
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
LodePNG version 20200306
|
||||
LodePNG version 20210627
|
||||
|
||||
Copyright (c) 2005-2020 Lode Vandevenne
|
||||
Copyright (c) 2005-2021 Lode Vandevenne
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -142,16 +142,24 @@ unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h,
|
|||
/*
|
||||
Load PNG from disk, from file with given name.
|
||||
Same as the other decode functions, but instead takes a filename as input.
|
||||
*/
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and decode in-memory.*/
|
||||
unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const char* filename,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
|
||||
/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/
|
||||
/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and decode in-memory.*/
|
||||
unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const char* filename);
|
||||
|
||||
/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/
|
||||
/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and decode in-memory.*/
|
||||
unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h,
|
||||
const char* filename);
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
|
@ -191,17 +199,26 @@ unsigned lodepng_encode24(unsigned char** out, size_t* outsize,
|
|||
/*
|
||||
Converts raw pixel data into a PNG file on disk.
|
||||
Same as the other encode functions, but instead takes a filename as output.
|
||||
|
||||
NOTE: This overwrites existing files without warning!
|
||||
*/
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and encode in-memory.*/
|
||||
unsigned lodepng_encode_file(const char* filename,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
LodePNGColorType colortype, unsigned bitdepth);
|
||||
|
||||
/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/
|
||||
/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and encode in-memory.*/
|
||||
unsigned lodepng_encode32_file(const char* filename,
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
|
||||
/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/
|
||||
/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and encode in-memory.*/
|
||||
unsigned lodepng_encode24_file(const char* filename,
|
||||
const unsigned char* image, unsigned w, unsigned h);
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
|
@ -223,6 +240,9 @@ unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
|||
/*
|
||||
Converts PNG file from disk to raw pixel data in memory.
|
||||
Same as the other decode functions, but instead takes a filename as input.
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and decode in-memory.
|
||||
*/
|
||||
unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
|
||||
const std::string& filename,
|
||||
|
@ -243,7 +263,11 @@ unsigned encode(std::vector<unsigned char>& out,
|
|||
/*
|
||||
Converts 32-bit RGBA raw pixel data into a PNG file on disk.
|
||||
Same as the other encode functions, but instead takes a filename as output.
|
||||
|
||||
NOTE: This overwrites existing files without warning!
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and decode in-memory.
|
||||
*/
|
||||
unsigned encode(const std::string& filename,
|
||||
const unsigned char* in, unsigned w, unsigned h,
|
||||
|
@ -270,12 +294,21 @@ struct LodePNGDecompressSettings {
|
|||
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
|
||||
unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/
|
||||
|
||||
/*use custom zlib decoder instead of built in one (default: null)*/
|
||||
/*Maximum decompressed size, beyond this the decoder may (and is encouraged to) stop decoding,
|
||||
return an error, output a data size > max_output_size and all the data up to that point. This is
|
||||
not hard limit nor a guarantee, but can prevent excessive memory usage. This setting is
|
||||
ignored by the PNG decoder, but is used by the deflate/zlib decoder and can be used by custom ones.
|
||||
Set to 0 to impose no limit (the default).*/
|
||||
size_t max_output_size;
|
||||
|
||||
/*use custom zlib decoder instead of built in one (default: null).
|
||||
Should return 0 if success, any non-0 if error (numeric value not exposed).*/
|
||||
unsigned (*custom_zlib)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGDecompressSettings*);
|
||||
/*use custom deflate decoder instead of built in one (default: null)
|
||||
if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate)*/
|
||||
if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate).
|
||||
Should return 0 if success, any non-0 if error (numeric value not exposed).*/
|
||||
unsigned (*custom_inflate)(unsigned char**, size_t*,
|
||||
const unsigned char*, size_t,
|
||||
const LodePNGDecompressSettings*);
|
||||
|
@ -454,30 +487,36 @@ typedef struct LodePNGInfo {
|
|||
unsigned background_b; /*blue component of suggested background color*/
|
||||
|
||||
/*
|
||||
non-international text chunks (tEXt and zTXt)
|
||||
Non-international text chunks (tEXt and zTXt)
|
||||
|
||||
The char** arrays each contain num strings. The actual messages are in
|
||||
text_strings, while text_keys are keywords that give a short description what
|
||||
the actual text represents, e.g. Title, Author, Description, or anything else.
|
||||
|
||||
All the string fields below including keys, names and language tags are null terminated.
|
||||
All the string fields below including strings, keys, names and language tags are null terminated.
|
||||
The PNG specification uses null characters for the keys, names and tags, and forbids null
|
||||
characters to appear in the main text which is why we can use null termination everywhere here.
|
||||
|
||||
A keyword is minimum 1 character and maximum 79 characters long. It's
|
||||
discouraged to use a single line length longer than 79 characters for texts.
|
||||
A keyword is minimum 1 character and maximum 79 characters long (plus the
|
||||
additional null terminator). It's discouraged to use a single line length
|
||||
longer than 79 characters for texts.
|
||||
|
||||
Don't allocate these text buffers yourself. Use the init/cleanup functions
|
||||
correctly and use lodepng_add_text and lodepng_clear_text.
|
||||
|
||||
Standard text chunk keywords and strings are encoded using Latin-1.
|
||||
*/
|
||||
size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/
|
||||
char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/
|
||||
char** text_strings; /*the actual text*/
|
||||
|
||||
/*
|
||||
international text chunks (iTXt)
|
||||
International text chunks (iTXt)
|
||||
Similar to the non-international text chunks, but with additional strings
|
||||
"langtags" and "transkeys".
|
||||
"langtags" and "transkeys", and the following text encodings are used:
|
||||
keys: Latin-1, langtags: ASCII, transkeys and strings: UTF-8.
|
||||
keys must be 1-79 characters (plus the additional null terminator), the other
|
||||
strings are any length.
|
||||
*/
|
||||
size_t itext_num; /*the amount of international texts in this PNG*/
|
||||
char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/
|
||||
|
@ -639,8 +678,19 @@ typedef struct LodePNGDecoderSettings {
|
|||
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/
|
||||
|
||||
/*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/
|
||||
unsigned remember_unknown_chunks;
|
||||
|
||||
/* maximum size for decompressed text chunks. If a text chunk's text is larger than this, an error is returned,
|
||||
unless reading text chunks is disabled or this limit is set higher or disabled. Set to 0 to allow any size.
|
||||
By default it is a value that prevents unreasonably large strings from hogging memory. */
|
||||
size_t max_text_size;
|
||||
|
||||
/* maximum size for compressed ICC chunks. If the ICC profile is larger than this, an error will be returned. Set to
|
||||
0 to allow any size. By default this is a value that prevents ICC profiles that would be much larger than any
|
||||
legitimate profile could be to hog memory. */
|
||||
size_t max_icc_size;
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
} LodePNGDecoderSettings;
|
||||
|
||||
|
@ -950,6 +1000,9 @@ out: output parameter, contains pointer to loaded buffer.
|
|||
outsize: output parameter, size of the allocated out buffer
|
||||
filename: the path to the file to load
|
||||
return value: error code (0 means ok)
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and decode in-memory.
|
||||
*/
|
||||
unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename);
|
||||
|
||||
|
@ -960,6 +1013,9 @@ buffer: the buffer to write
|
|||
buffersize: size of the buffer to write
|
||||
filename: the path to the file to save to
|
||||
return value: error code (0 means ok)
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and encode in-memory
|
||||
*/
|
||||
unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename);
|
||||
#endif /*LODEPNG_COMPILE_DISK*/
|
||||
|
@ -1000,12 +1056,18 @@ unsigned encode(std::vector<unsigned char>& out,
|
|||
/*
|
||||
Load a file from disk into an std::vector.
|
||||
return value: error code (0 means ok)
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and decode in-memory
|
||||
*/
|
||||
unsigned load_file(std::vector<unsigned char>& buffer, const std::string& filename);
|
||||
|
||||
/*
|
||||
Save the binary data in an std::vector to a file on disk. The file is overwritten
|
||||
without warning.
|
||||
|
||||
NOTE: Wide-character filenames are not supported, you can use an external method
|
||||
to handle such files and encode in-memory
|
||||
*/
|
||||
unsigned save_file(const std::vector<unsigned char>& buffer, const std::string& filename);
|
||||
#endif /* LODEPNG_COMPILE_DISK */
|
||||
|
@ -1505,6 +1567,11 @@ of the error in English as a string.
|
|||
|
||||
Check the implementation of lodepng_error_text to see the meaning of each code.
|
||||
|
||||
It is not recommended to use the numerical values to programmatically make
|
||||
different decisions based on error types as the numbers are not guaranteed to
|
||||
stay backwards compatible. They are for human consumption only. Programmatically
|
||||
only 0 or non-0 matter.
|
||||
|
||||
|
||||
8. chunks and PNG editing
|
||||
-------------------------
|
||||
|
@ -1678,6 +1745,9 @@ try to fix it if the compiler is modern and standards compliant.
|
|||
This decoder example shows the most basic usage of LodePNG. More complex
|
||||
examples can be found on the LodePNG website.
|
||||
|
||||
NOTE: these examples do not support wide-character filenames, you can use an
|
||||
external method to handle such files and encode or decode in-memory
|
||||
|
||||
10.1. decoder C++ example
|
||||
-------------------------
|
||||
|
||||
|
@ -1775,6 +1845,10 @@ symbol.
|
|||
Not all changes are listed here, the commit history in github lists more:
|
||||
https://github.com/lvandeve/lodepng
|
||||
|
||||
*) 27 jun 2021: added warnings that file reading/writing functions don't support
|
||||
wide-character filenames (support for this is not planned, opening files is
|
||||
not the core part of PNG decoding/decoding and is platform dependent).
|
||||
*) 17 okt 2020: prevent decoding too large text/icc chunks by default.
|
||||
*) 06 mar 2020: simplified some of the dynamic memory allocations.
|
||||
*) 12 jan 2020: (!) added 'end' argument to lodepng_chunk_next to allow correct
|
||||
overflow checks.
|
||||
|
@ -1941,5 +2015,5 @@ Domain: gmail dot com.
|
|||
Account: lode dot vandevenne.
|
||||
|
||||
|
||||
Copyright (c) 2005-2020 Lode Vandevenne
|
||||
Copyright (c) 2005-2021 Lode Vandevenne
|
||||
*/
|
||||
|
|
|
@ -1002,9 +1002,9 @@ static DWORD ReadT2Acc(VOID)
|
|||
// maybe CPU speed measurement, slow down the next 10 CPU opcodes
|
||||
if (dwCycDif < 150)
|
||||
{
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
EnterCriticalSection(&csSlowLock);
|
||||
{
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
nOpcSlow = 10; // slow down next 10 opcodes
|
||||
}
|
||||
LeaveCriticalSection(&csSlowLock);
|
||||
|
|
|
@ -504,21 +504,13 @@ VOID SoundOut(CHIPSET* w, WORD wOut)
|
|||
}
|
||||
|
||||
// ran out of buffers -> disable CPU slow down
|
||||
EnterCriticalSection(&csSlowLock);
|
||||
{
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
bEnableSlow = (GetSoundBufSize() > 1);
|
||||
}
|
||||
LeaveCriticalSection(&csSlowLock);
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
bEnableSlow = (GetSoundBufSize() > 1);
|
||||
|
||||
if (bSoundSlow == FALSE)
|
||||
{
|
||||
EnterCriticalSection(&csSlowLock);
|
||||
{
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
bSoundSlow = TRUE; // CPU slow down
|
||||
}
|
||||
LeaveCriticalSection(&csSlowLock);
|
||||
InitAdjustSpeed(); // init variables if necessary
|
||||
bSoundSlow = TRUE; // CPU slow down
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -303,7 +303,7 @@ FONT 8, "MS Sans Serif"
|
|||
BEGIN
|
||||
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
|
||||
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
|
||||
LTEXT "Copyright © 2020 Christoph Gießelink && Sébastien Carlier",
|
||||
LTEXT "Copyright © 2021 Christoph Gießelink && Sébastien Carlier",
|
||||
IDC_STATIC,29,18,181,8
|
||||
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
|
||||
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
|
||||
|
@ -752,8 +752,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,6,3,0
|
||||
PRODUCTVERSION 1,6,3,0
|
||||
FILEVERSION 1,6,4,0
|
||||
PRODUCTVERSION 1,6,4,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -770,12 +770,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 6, 3, 0\0"
|
||||
VALUE "FileVersion", "1, 6, 4, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2020\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2021\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 6, 3, 0\0"
|
||||
VALUE "ProductVersion", "1, 6, 4, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -67,4 +67,4 @@ Many thanks to Pedro A. Arranda Guti
|
|||
compatible.
|
||||
|
||||
|
||||
09/17/20 (c) by Christoph Gießelink
|
||||
09/26/21 (c) by Christoph Gießelink
|
||||
|
|
BIN
uninst.exe
BIN
uninst.exe
Binary file not shown.
Loading…
Reference in a new issue