Compare commits

...

330 Commits
v2.5 ... master

Author SHA1 Message Date
David Korth
19e50372da [librptexture] ICO: For Win1.x icons with both DIB and DDB, show both in the icon directory.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
The DDB is usually half the size of the DIB.

NOTE: The DDB, which comes after the DIB, is missing the format WORD.
The header is otherwise the same format.

Rename vv_icons to v_icons, since it's not a vector of vectors.
2025-06-17 20:09:41 -04:00
David Korth
37dcb72e6b CMakeLists.txt: Use .99 versions for CMake VERSION_GREATER checks. 2025-06-16 21:44:24 -04:00
David Korth
2613201bb3 NEWS.md: Mention the 'abgr' swizzle issue on little-endian systems. 2025-06-16 19:46:40 -04:00
David Korth
aeb568dda3 [librptexture] rp_image::swizzle(): Fix the 'rgba' check.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
Need to byteswap it on little-endian. Otherwise, it'll end up catching
'abgr' instead.

Also, add a big-endian check on Neon, since it's possible for ARM to
operate in big-endian mode.
2025-06-16 19:33:16 -04:00
David Korth
a138b123e3 [librptexture] qoi.h: Swap R/B in qoi_encode() and qoi_decode().
This eliminates the need to call rp_image::swizzle() in
QoiPrivate::loadImage().

qoi.h now expects images to be in the same ARGB32 format
as the rest of rom-properties.

NOTE: Only adjusting what's read from or written to bytes[],
not the internal pixel buffers.
2025-06-16 19:32:30 -04:00
David Korth
4badcf4bfb [libromdata/tests] ImageDecoderTest: Add two Qoi test images.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
- argb-reference.qoi: Qoi version of argb-reference.png
- rgb-reference.qoi: Qoi version of rgb-reference.png
2025-06-16 01:06:17 -04:00
David Korth
b0d5e05cce [librptexture] qoi.h: Revert the qoi_decode() change.
A new test I added failed with the qoi_decode() change. Reverting it
fixes the test, even with the qoi_read_32() optimization still in place.
2025-06-16 01:05:40 -04:00
David Korth
523de9913c [librptexture] qoi.h: Optimize 32-bit reads and writes.
...for the basic read/write functions and qoi_decode().

qoi_encode() isn't being used at the moment, so I'm not going to try
to optimize it.

TODO: Verify that the memcpy()'s don't break on big-endian.
2025-06-16 00:57:49 -04:00
David Korth
f0ee7bee10 [librptexture] Qoi: qoi.h has the R and B channels swapped compared to what rp_image expects.
This was broken since support for Qoi was added in v2.5. Not sure why
I didn't notice it until now...

Affects: v2.4 - v2.5
2025-06-16 00:51:54 -04:00
David Korth
c3643b9244 [libpng] Update: v1.6.48 -> v1.6.49
Includes the APNG patch.
2025-06-15 14:25:09 -04:00
David Korth
72b628d8ba [win32] RP_ShellPropSheetExt_Private::initListData(): Use nearest-neighbor for integer upscaling. 2025-06-15 11:35:55 -04:00
David Korth
933b3d2f4e NEWS.md: Mention KF5/KF6 RFT_LISTDATA image quality improvements. 2025-06-15 11:25:53 -04:00
David Korth
eee8b83f9a [kde] ListDataModel::updateIconPixmaps(): Improve icon scaling on Qt5 and Qt6.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
Instead of scaling larger icons down, set a device pixel ratio. For the
usual case of iconSize = (32, 32), on a 200% display, the actual physical
icon size is (64, 64). Xbox 360 achievement icons are 64x64, so this will
show the full icon on a 200% display instead of scaling down to 32x32,
then scaling back up to 64x64.

For icons smaller than 32x32, the icon is scaled up using integer factors
to the next highest integer multiple that's >= 32x32, then the device
pixel ratio is set.

NOTE: GTK+ doesn't seem to have the same issue.

TODO: Verify Win32, especially with icon directories.
2025-06-15 11:17:42 -04:00
David Korth
b19f128903 [librptexture] ICOPrivate::~ICOPrivate(): Use dir.is_res instead of isResource().
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
Removed isResource().
2025-06-13 18:35:18 -04:00
David Korth
73eb28c4ee [librptexture] ICO: Show the icon directory with all the icon variants.
For standalone Win3.x icons and cursors only.

Color depth and format are shown, including if it's PNG format.

ICOPrivate::loadImage(): Remove caching stuff, since it's handled
by ICO::loadInternalImage().
2025-06-13 18:30:09 -04:00
David Korth
e5c512ca92 [rp-download] SetFileOriginInfo_win32.cpp: Load NTDLL.DLL function pointers using GetProcAddress().
AppVeyor's MSVC 2015 image doesn't have ntdll.lib for some reason.
2025-06-13 18:14:49 -04:00
David Korth
1da1c39c18 [librptexture] ICO: Remove pIconHeader.
Use dir.bestIcon_idx as an index into d->iconBitmapHeaders[] instead.
2025-06-13 18:13:16 -04:00
David Korth
da852e5d50 [librptexture] ICOPrivate::loadIconDirectory_Win3(): Missed an le32_to_cpu(). 2025-06-13 18:08:02 -04:00
David Korth
f157be4a97 [rp-download] SetFileOriginInfo_win32.cpp: Use NTDLL to write the Alternate Data Stream with just the file handle.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
Note that we have to use NtWriteFile(). Using WriteFile() results in
ERROR_BAD_COMMAND.

If the ADS write fails, it will be deleted with NtDeleteFile().

NOTE: Unicode only! ANSI builds won't write the ADS anymore.
ANSI builds (if they even work at all) should only be used on
Win9x, which doesn't support ADS anyway.

TODO: Convert NTSTATUS to POSIX error codes?
2025-06-12 23:33:56 -04:00
David Korth
a19815f744 [librptexture] ICO: Remove imageResType() in favor of dir.rt and dir.is_res.
This simplifies the code a bit more and removes some function calls.

dir.rt is the individual bitmap resource type: RT_ICON, RT_CURSOR
dir.is_res is true for .exe/.dll resources, and false for .ico/.cur files.
2025-06-12 22:00:05 -04:00
David Korth
a5554fd244 [librptexture] ICO: Remove pBestIcon from the icodir structs. Use an index instead.
This simplifies things a bit.
2025-06-12 21:42:18 -04:00
David Korth
0c512deed6 [librptexture] ICO: Rework the private loadImage_*() functions (except Win1) to take a bitmap image index.
This will allow us to show a list of all the bitmaps in a given icon.

NOTE: loadInternalImage() ensures that d->img_icon is set to the "best"
icon; that is, icon index "-1". The loadImage_*() functions won't use
d->img_icon themselves, so if the "best" icon is manually selected
using positive indexes, it won't be cached.
2025-06-12 21:31:09 -04:00
David Korth
704a5eead5 [librptexture] ICOPrivate::loadImage_WinVista_PNG(): Use res.pBestIcon->nID instead of res.id.
res.id may have accidentally worked because it was set to -1, but it's
the ID of the RT_GROUP_ICON, not the RT_ICON.
2025-06-12 21:11:41 -04:00
David Korth
783d384b04 [libromdata] EXE: Add .mui and .mun to the file extensions list.
.mui is a resource DLL used for localization.

.mun is used in Windows 10 1903+ (or possibly slightly earlier) for
icons in C:\Windows\SystemResources\ , instead of storing icons in
e.g. notepad.exe.
2025-06-12 21:07:21 -04:00
David Korth
9ca7daf9c8 [libromdata] EXE: No application icon if it's not NE/PE or not an executable.
Also, add d->file.reset() to more error paths in the constructor.
2025-06-12 21:06:01 -04:00
David Korth
c31919826b [libromdata] IsoPartitionPrivate::getDirectory(): Fix an inverted comment. 2025-06-12 20:58:57 -04:00
David Korth
bf2d3af7c3 [gettext.win32] Updated to gettext-0.25.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
Compiled with:
- i386:  gcc-15.1.0, MinGW-w64 12.0.0
- amd64: gcc-15.1.0, MinGW-w64 12.0.0

The file sizes have grown a bit. In particular, xgettext.exe grew from
1,529,344 bytes to 8,492,544 bytes. This might be related to various
gnulib updates, since libgnuintl-8.dll has a bunch of new exports
compared to 0.24.
2025-06-11 22:30:05 -04:00
David Korth
e2eede76f7 Merge branch 'feature/IsoPartition-readdir'
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
Includes:
- IsoPartition::readdir()
- ISO-9660 Joliet support
- ICO parser (for Win1.x and Win3.x)
- EXE thumbnailing (for Win1.x, Win3.x, and Win32/Win64)
- ISO thumbnailing via AUTORUN.INF
2025-06-09 23:48:08 -04:00
David Korth
e12bb51b47 [librptexture] ICOPrivate::loadImage_Win3(): Move the bitmap size check up a bit.
Some checks failed
Codecov / run (push) Has been cancelled
2025-06-09 21:05:24 -04:00
David Korth
417825cd6f [librptexture] ICO: Handle Win3.x 1bpp (monochrome) icons.
Tested by converting Win2.x BANG.ICO to Win3.x format.

ICOPrivate::loadImage_Win1():
- Note that the mask is *before* the icon.

ImageDecoder::fromLinearMono_WinIcon():
- Take separate pointers for the icon and mask data. Win3.x icons are
  typically stored upside-down, so this lets us handle that outside
  of the decoder function. This also means the image data size does
  not have to be 2x. Note that `img_siz == mask_siz` must be true.
2025-06-09 20:21:25 -04:00
David Korth
da94256a37 [xdg] mime.no-thumbnail.types: Add Windows icon/cursor MIME types.
FIXME: KDE isn't showing the ROM Properties tab on .ico files,
but Thunar and Nautilus show it just fine...
2025-06-09 20:00:09 -04:00
David Korth
222f2456fd [librptexture] ICOPrivate::loadImage_Win3(): Minor adjustment to the assertion message. 2025-06-09 19:45:04 -04:00
David Korth
11da731ef7 [librptexture] ICOPrivate::loadImage_Win3(): Add assertions for unsupported icon formats.
TODO: Need a test icon for Win3.x monochrome icons.
2025-06-09 19:43:51 -04:00
David Korth
a4efadbc56 NEWS.md: Mention issues #170 and #232. 2025-06-09 19:28:52 -04:00
David Korth
0e1a5ce237 [libromdata] ISO::loadFieldData(): Show the AUTORUN.INF fields in a new tab.
The fields are displayed as-is.

Changed autorun_inf from unordered_map<> to map<> for alphabetical sorting.
TODO: Preserve the original sort order?

TODO: Store the original key case?
2025-06-09 19:26:40 -04:00
David Korth
d557b607c2 [[libromdata] ISO: Only load the "[autorun]" section for now.
TODO: Read more sections later.
2025-06-09 19:21:47 -04:00
David Korth
1897ac198f [libromdata] ISO: Load the entire AUTORUN.INF for display purposes.
It's not displayed yet, but it's loaded.

The section names are concatenated with the key names, e.g.:
"autorun|icon"

IsoPartition::open(): Set m_lastError = ENOENT if the file isn't found.
2025-06-09 19:18:31 -04:00
David Korth
5083161c23 [librptexture] ICO: Fix regression that broke Win3.x icons; remove unneeded assert().
ICOPrivate::loadIconDirectory_Win3():
- rt == res.type *only* for Win1.x. For Win3.x, res.type is RT_GROUP_ICON
  or RT_GROUP_CURSOR. For Win1.x, it's RT_ICON or RT_CURSOR.

This fixes a regression from commit 22da0c2e21.
([libromdata] EXE: Load icons from Windows 1.x/2.x executables.)
2025-06-09 18:50:44 -04:00
David Korth
22da0c2e21 [libromdata] EXE: Load icons from Windows 1.x/2.x executables.
Windows 1.x/2.x does not have RT_GROUP_ICON. For NE executables,
check for RT_GROUP_ICON, and use it if found. Otherwise, check for
RT_ICON and use that if found.

IResourceReader: Add a function has_resource_type() to check if the
executable has any resources of the specified type.

[librptexture] ICO: Handle RT_ICON and RT_CURSOR as Windows 1.x/2.x.
TODO: Check the header to verify?
2025-06-09 18:37:47 -04:00
David Korth
8f762b7c78 ICOPrivate::ICOPrivate(): Return if the type is unrecognized.
Otherwise, dir.res will be allocated, with unpredictable results.
2025-06-09 18:30:01 -04:00
David Korth
acdf3544e1 [libromdata] NEResourceReader::lookup_resource_ID(): OR the type with 0x8000.
With Win16, the high bit needs to be set for ordinal resources.
Otherwise, it's a named resource, which we don't support right now.

Thumbnailing still worked because we were using the code path for
the "first" icon using NEResourceReader::open(), which had the
`| 0x8000` bit already.
2025-06-09 18:24:34 -04:00
David Korth
bb2e0b5e87 [kde] AchQtDBus::notifyFunc(): Fix the Qt4 build.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
2025-06-09 18:13:47 -04:00
David Korth
65a3855b98 [libromdata] NEResourceReaderPrivate::loadResTbl(): Fix an off-by-one error that broke reading resources from SkiFree 1.0.
SkiFree doesn't have any named resources, so its resource table ends
immediately after rscEndTypes. The off-by-one prevented us from
recognizing the presence of rscEndTypes.

SKI.EXE can now be thumbnailed.
2025-06-09 18:11:03 -04:00
David Korth
847342306a [libromdata] NEResourceReaderPrivate::loadResTbl(): Allow string names for now.
Some Windows 3.1 programs, e.g. CALC.EXE, have RT_GROUP_ICONs that use
string names. We need to allow this in order to thumbnail CALC.EXE.
2025-06-09 18:08:50 -04:00
David Korth
3fdd98929d [libromdata] IsoPartition: Update the "\x00" and "\x01" comments. 2025-06-08 16:10:11 -04:00
David Korth
41765be492 NEWS.md: Mention the ISO and Windows icon changes. 2025-06-08 15:53:24 -04:00
David Korth
4342ce8a1b [libromdata] ISO, IsoPartition: Simplify the Joliet escape sequence parser a bit. 2025-06-08 15:29:25 -04:00
David Korth
6e7d57282f [libromdata] ISO: Show the Joliet level.
Some checks are pending
Codecov / run (push) Waiting to run
I was considering exporting this from IsoPartition, but the IsoPartition
isn't accessible at this point. We're reading all of the volume
descriptors in checkVolumeDescriptors() anyway, so that sets a local
version of jolietSVDType, which is then checked in loadFieldData().
2025-06-08 15:00:39 -04:00
David Korth
3f1f92b18a [libromdata] IsoPartition: Add basic support for Joliet directories.
If a Supplementary Volume Descriptor is present, check for the Joliet
UCS-2 escape sequences. If found, use the SVD root directory.

Filenames in the SVD root directory are encoded in UCS-2 (big-endian).
The filename length is in bytes, not code points.

NOTE: Currently using a very cheap hack to convert UCS-2 to cp1252,
or more accurately, ISO-8859-1. It's good enough for our purposes
for now. (specifically, getting the icon from AUTORUN.INF.)

TODO: Better character set conversion.
2025-06-08 14:46:56 -04:00
David Korth
a5d22511e0 [libromdata] IsoPartition::readdir(): If there's no more non-zero bytes, return nullptr.
Otherwise, an empty IFst::DirEnt is returned.
2025-06-08 14:44:49 -04:00
David Korth
618c7c6a8d [librptexture] ICO: Fix an implicit cast warning on 64-bit MSVC.
Some checks are pending
Codecov / run (push) Waiting to run
src\librptexture\fileformat\ICO.cpp(642,11): warning C4267: '+=':
	conversion from 'size_t' to 'unsigned int', possible loss of data
2025-06-08 13:07:55 -04:00
David Korth
9a4ab48ccb [libromdata] RomDataFactory: s/exe/ext/
This fixes a Windows build regression from commit 9994c2df94.
([libromdata] RomDataFactory: Explicitly prevent ".ico" and ".cur" from being thumbnailed on Windows.)
2025-06-08 13:05:31 -04:00
David Korth
64fe76a285 [librpbase] exe_res_structs.h: Don't re-define version resource stuff if winver.h is already included.
This should fix the Windows build.
2025-06-08 13:04:12 -04:00
David Korth
993e52084d [librpbase] IResourceReader: New function lookup_resource_ID().
This function takes a zero-based index and returns a resource ID for
the given resource type if it's within range. Otherwise, it returns
a negative POSIX error code.

[libromdata] PEResourceReader, NEResourceReader: Implement it.

[libromdata] EXE: Use lookup_resource_ID for positive icon indexes.

This fixes thumbnailing for discs whose AUTORUN.INF specify a
positive, non-zero icon index.

TODO: Older discs may have truncated ISO-9660 filenames. Need to
parse Joliet file systems, maybe...
2025-06-08 12:44:35 -04:00
David Korth
55cad0ad98 [libromdata] ISO: Parse the icon index for EXE/DLL autorun icons.
The icon index can be:
- 0: First icon
- >0: Zero-based icon index
- <0: Resource ID

EXE: New function loadSpecificIcon() to load an icon given an index.
For iconindex == 0, the icon is cached in d->img_icon.

TODO: Implement a function in IResourceReader to look up a resource ID
from the zero-based index.
2025-06-08 12:23:37 -04:00
David Korth
93e78417e0 [libromdata] ISO: Load AUTORUN.INF icons from EXEs and/or DLLs.
TODO: Handle the icon index.
2025-06-08 11:54:45 -04:00
David Korth
453461e8fb [librptexture] ICOPrivate::loadImage_Win3(): Need to skip the BITMAPINFOHEADER when parsing resource icons.
This fixes the corrupted 128x128 VBoxGuestAdditions.exe icon.
2025-06-08 11:54:34 -04:00
David Korth
f5be3c81a4 [libromdata] EXE: Add icon thumbnailing using librptexture's ICO class.
Uses the first icon in the first available language.

New function loadResourceReader() which ensures rsrcReader is loaded.

[librptexture] ICO: Fix resource loading issues:

- Use the correct resource file pointer, not this->file.
- Add IconRes_Win3 and CursorRes_Win3 cases where appropriate.
- Ensure d->iconType doesn't get overwritten after it's set by the
  ICOPrivate constructor for resources.

FIXME: VBoxWindowsAdditions.exe's PNG icon loads fine, but the 128x128
"regular" icon is corrupted.
2025-06-08 11:40:59 -04:00
David Korth
9994c2df94 [libromdata] RomDataFactory: Explicitly prevent ".ico" and ".cur" from being thumbnailed on Windows.
Also add a note saying EXE shouldn't be registered for thumbnailing,
either.

This will still allow using `rpcli`, and for subclasses to use
EXE to thumbnail e.g. ISO images.
2025-06-08 11:12:06 -04:00
David Korth
6026b40df5 [libromdata] PlayStationDiscPrivate::loadSystemCnf(): Use a constant for the SYSTEM.CNF maximum size. 2025-06-08 02:33:38 -04:00
David Korth
409915591d [libromdata] ISOPrivate::loadIcon(): f_file.reset() isn't needed here. 2025-06-08 02:31:45 -04:00
David Korth
8c5888e9e5 [librptexture] ICO: Rework to support loading from Windows resources.
Some checks are pending
Codecov / run (push) Waiting to run
NOT TESTED; need to add it to the EXE class to test it.
(.ico files still work as they did before.)

Added a constructor that takes an IResourceReaderPtr and the
type/id/lang of the icon. Type should be RT_GROUP_ICON or
RT_GROUP_CURSOR. These are all saved in icodir_res.

The dir union is now initialized in the ICOPrivate constructors,
and is only reset in the ICOPrivate destructor.

loadImage_Win3(): Use a new IRpFilePtr for the icon data.
- For .ico, it's a copy of this->file.
- For Windows executables, it's opened from the IResourceReader.
- Starting address is the icon bitmap address for .ico and
  0 for IResourceReader.
2025-06-08 00:14:28 -04:00
David Korth
d0fb8dc73e [libromdata] ISO::imgpf(): Remove unused RP_D() for now, and an extra 'break;' statement.
In file included from src/libromdata/stdafx.h:63,
                 from src/libromdata/Media/ISO.cpp:10:
src/libromdata/Media/ISO.cpp: In member function ‘virtual uint32_t LibRomData::ISO::imgpf(LibRpBase::RomData::ImageType) const’:
src/libromdata/../common.h:93:45: warning: unused variable ‘d’ [-Wunused-variable]
   93 | #  define RP_D(klass) klass##Private *const d = static_cast<klass##Private*>(d_ptr)
      |                                             ^
src/libromdata/Media/ISO.cpp:984:9: note: in expansion of macro ‘RP_D’
  984 |         RP_D(const ISO);
      |         ^~~~
2025-06-07 23:30:31 -04:00
David Korth
a837c883ee [librptexture] FileFormat_decl.hpp: -'file' 2025-06-07 23:29:08 -04:00
David Korth
44ad904c71 Move IResourceReader from libromdata to librpbase.
This will allow us to use it in librptexture's ICO handler.
2025-06-07 23:26:31 -04:00
David Korth
b3b6eb5b37 [librptexture] CMakeLists.txt: Add ico_structs.h. 2025-06-07 23:19:03 -04:00
David Korth
95bcbc25fb [librptexture] ICO: Use a union of structs containing the different types of directory entries.
This is a bit cleaner than the casting method, though it is a bit messy
at points.

isResource(): Returns true if it's an icon from a resource.
(Currently not set at all...)

reset_dir_union(): Clear the directory union. Called in ICOPrivate's
destructor and various error paths.

TODO: Add resource loading. May need to move IResourceReader from
libromdata to librpbase.
2025-06-07 23:15:15 -04:00
David Korth
821155bd83 [librptexture] ICO: Initial reworking to handle icons from .exe/.dll resources.
ICONDIR and GRPICONDIR are basically the same, but ICONDIRENTRY and
GRPICONDIRENTRY have different sizes. Use an rp::uvector<uint8_t>
and casting to handle this.

Still only supports .ico files for now.
2025-06-07 23:09:45 -04:00
David Korth
e765792ebb [libromdata] ISO: Initial support for AUTORUN.INF icons.
Limitations:
- Only supports .ico, not .exe.
- The filename must match the ISO-9660 filename. Some older Win9x
  discs use a long filename in AUTORUN.INF that's only listed as
  such in the Joliet extension.

Removed some debugging code from the IsoPartition readdir()
implementation testing from earlier.
2025-06-07 22:38:31 -04:00
David Korth
194b3dcf61 [librptexture] fromLinearCI8(): Require 32-bit palettes for all Host_* and Swap_* formats.
TODO:
- More formats?
- Add a table mapping pixel format to bpp?
2025-06-07 22:05:56 -04:00
David Korth
8378697be1 [librptexture] ICOPrivate::loadImage_Win3(): Use Host_ARGB32, not Host_xRGB32, for the palette.
fromLinearCI4() doesn't support Host_xRGB32, and we're filling
in the alpha channel ourselves.

TODO: Add Host_xRGB32 support to fromLinearCI4()?
fromLinearCI8() supports it...

This fixes a regression from commit de802835f7.
([librptexture] ICO: Handle 8-bit color icons.)
2025-06-07 22:03:17 -04:00
David Korth
1caf44d15e [librptexture] ICO: Select the best icon image.
First, the image size is checked. If either width or height are larger
than the previously-selected image, this image is picked. Otherwise,
if the size is identical (both width and height), and bitcount is
higher, then the image is selected.

TODO: Better non-square icon handling? (Use "largest area"?)
2025-06-07 21:50:37 -04:00
David Korth
fbdeae25a5 [librptexture] ICO: Load all of the icon bitmap headers.
Next step is to actually go through them and pick the "best" one.
2025-06-07 21:35:16 -04:00
David Korth
de802835f7 [librptexture] ICO: Handle 8-bit color icons.
- Forgot to move convimg to img when converting from CI8 to ARGB32.

- Make sure sBIT is updated with alpha=1. Otherwise, RpPng::save()
  will tell libpng that there's no alpha, so the resulting PNG image
  saved using `rpcli -x3` won't be transparent.
2025-06-07 21:27:47 -04:00
David Korth
1c96133917 [librptexture] ICO: Divide the bitmap height by 2 for d->dimensions[1].
The ICONDIR height is correct, but the bitmap height is double-sized
because it includes the mask.
2025-06-07 21:19:54 -04:00
David Korth
d01201a184 [librptexture] ICO: Save the icon image header and get sizes for BITMAPCOREHEADER and PNG.
iconHeader is now saved in the private class instead of being loaded
in loadImage_Win3().

The dimensions are now set correctly when an icon's "best" image is
in PNG format.

ico_structs.h: Add PNG chunks.
2025-06-07 21:15:50 -04:00
David Korth
f6e5229b72 [librptexture] ICO: Load PNG-format icon images.
FIXME: Dimensions are still incorrect, since the ICONDIR dimensions
are 0 for 256x256. We should get the dimensions from IHDR instead.
2025-06-07 21:04:18 -04:00
David Korth
fe85d93fc3 [librptexture] ICOPrivate::loadImage_Win3(): Add support for 32-bit ARGB icons.
NOTE: BI_BITFIELDS is not supported right now. (Is that even used for
32-bit ARGB, or is it for 16/24 only?)

Fix mask handling for 48x48 icons by aligning stride to 32-bit.
2025-06-07 20:52:45 -04:00
David Korth
7edb6df2e4 [librptexture] ICOPrivate::loadImage_Win3(): Apply the icon mask for 8bpp and higher icons.
NOTE: Not tested yet!

Remove an unused variable that was used when debugging masks.
The variable counted the number of mask bytes that were processed.
2025-06-07 20:25:16 -04:00
David Korth
eb5300413b [librptexture] ICOPrivate::loadImage_Win3(): Apply the icon mask for 1bpp, 2bpp, and 4bpp icons.
For these icons, an extra transparent color is added.

The image is flipped *after* the mask is applied because the mask is
also upside-down.

TODO:
- Set sBIT.
- Apply the icon mask for CI8 and higher-color icons. (CI8 will need to
  be converted to ARGB32.)
2025-06-07 20:21:22 -04:00
David Korth
37dd0c3ffe [librptexture] ICOPrivate::loadImage_Win3(): Fix mask_data address for upside-down bitmaps.
This seems to place the mask image at the top of the image once it's
flipped, but maybe it's that it's technically two bitmaps and not
one giant bitmap.

TODO: Test it with a right-side up icon.
2025-06-07 20:18:10 -04:00
David Korth
af2c512181 [librptexture] ICO: Initial support for Windows 3.x icons.
The entire icon directory is loaded, but currently the first icon is
loaded instead of selecting the "best" icon.

NOTE: Windows Vista and later determines the "best" icon by looking at
the BITMAPINFOHEADER, not the icon directory. We'll do that too.

loadImage_Win3(): Added support for loading 16-color icons, including
the palette (color table). The mask is loaded, but it isn't applied
yet.

TODO:
- Support more icon formats.
- Apply the mask.
- Determine if the mask isn't present? (e.g. in 32-bit icons)
2025-06-07 19:57:19 -04:00
David Korth
b02a2b8009 [librptexture] ICO: Remove duplicated code from the Qoi handler.
I used Qoi.cpp as a base for ICO.cpp.
2025-06-07 18:29:09 -04:00
David Korth
081d4a4b87 [librptexture] fromLinearMono_WinIcon(): Use white for INVERT.
This at least allows it to show up at all, whereas before it was
showing up as completely transparent.
2025-06-07 18:27:26 -04:00
David Korth
776998d0ed [librptexture] ImageDecoder_Linear_Gray.cpp: New function fromLinearMono_WinIcon().
This converts the Windows 1bpp icon using the mask for transparency.
(Inversion is *not* supported.)

Also, 0 == black, 1 == white. This is the opposite of fromLinearMono(),
which is mostly used for things like VMU icons.

TODO: Handle upside-down images. Win1.x icons and cursors are
right-side up, but Win3.x is upside-down.

ICOPrivate::loadImage_Win1(): Call fromLinearMono_WinIcon().

Tested with the Windows 2.0 DDK icons and cursors, and all of them
appear to be decoding correctly.
2025-06-07 18:24:42 -04:00
David Korth
e84ccfd53d [librptexture] ICO: Initial Windows Icon decoder.
This will eventually be used for ISO image thumbnailing, though it might
also be useful on some other systems.

Linux desktop environments typically have their own ICO thumbnailer.

NOTE: This might still be useful even if the system supports ICO:
- 64-bit Windows cannot read 16-bit Windows executables.
- No current Windows version supports Windows 1.x icons.
- Linux thumbnailers typically don't support Windows 1.x icons, either.

This implementation currently *only* supports Windows 1.x icons, and
doesn't handle masking.

TODO: ImageDecoder::fromLinearMono_WinIcon()?

NOTE: Icon MIME types haven't been added to the XDG files yet, so they
won't be thumbnailed yet (or, more likely, conflict with the system
thumbnailer).
2025-06-07 18:18:24 -04:00
David Korth
e2f0b41964 [libromdata] IsoPartitionPrivate::lookup_int(): Validate isDir in the exact-length match block. 2025-06-07 17:01:13 -04:00
David Korth
c65ea8c0ed [libromdata] IsoPartitionPrivate::getDirectory(): Fail if the entry isn't a directory.
Otherwise, it might try to load the file data as if it's a directory,
which would result in weird shenanigans.
2025-06-07 16:58:07 -04:00
David Korth
988df314e6 [libromdata] IsoPartition: New function sanitize_path() to remove leading and trailing slashes.
This fixes opendir("/NT3x/") for VBoxGuestAdditions.iso.

Note that this may be slightly slower than the old method due to string
copying, but it's much cleaner.

findLastSlash(): Now uses an internal function with a `size` parameter,
and has two wrapper functions: one for `const char*`, and one for
`std::string`.
2025-06-07 16:55:28 -04:00
David Korth
a49fb884f1 [libromdata] IsoPartition: Optimize findLastSlash() by searching for '/' and '\\' at the same time instead of calling strrchr() twice. 2025-06-07 16:39:46 -04:00
David Korth
c7ccd7a39a [librpbase] IsoPartition: Implement opendir(), readdir(), and closedir().
Tested using VBoxGuestAdditions.iso from VirtualBox 7.1.8.

Skip subdirectories with names "\x00" and "\x01". These are Joliet
"special directory identifiers".

IFst:
- Change `dir_idx` from int to intptr_t.
- Add two explicit constructors with a `dir_idx` parameter.
  One takes intptr_t; the other takes void*.
- Added an `extra` parameter for temporary filename storage.
  The ISO-9660 directory entry does not have NULL termination for
  the filename, so we need the temporary buffer to add the terminator.

GcnFst, WiiUFst:
- Update for the `dir_idx` constructor parameter.
- Zero out the `extra` parameter.

TODO:
- Move it to a new IFst subclass, IsoFst?
- Remove the file version number, e.g. ";1"?
- Handle "/NT3x/". Currently, "/NT3x" works, but the trailing slash
  confuses the directory lookup function.
- Joliet subdirectory support?
2025-06-07 16:34:00 -04:00
David Korth
6b30dd5b70 [libromdata] IsoPartition: Mark findLastSlash() and parseTimestamp() as static.
They don't depend on any data in IsoPartitionPrivate.

TODO: HSFS/CDI support?
2025-06-07 15:52:29 -04:00
David Korth
5ed38edbec [libromdata] IFst::readdir(): Return const DirEnt* instead of DirEnt*.
This ensures the caller won't modify the DirEnt.

Note that this doesn't match POSIX readdir(), but we don't need to
strictly match it. (We're also not returning `struct dirent*`; we're
returning a custom one.)
2025-06-07 15:47:30 -04:00
David Korth
b884747254 [librpbase] IFst.hpp: Un-indent the class definition. 2025-06-07 15:27:05 -04:00
David Korth
1aad707f88 [libromdata] WiiUPackagePrivate::addFields_System_XMLs(): Use C strings instead of C++ strings for the XML keys.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
Reduces memory usage slightly and probably improves performance a bit,
since we don't have to manage buffer sizes.

Code size differences: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
  15953     288       0   16241    3f71 WiiUPackage_xml.cpp.o [before]
  13376     288       0   13664    3560 WiiUPackage_xml.cpp.o [after]
  -2577       0       0   -2577    -a11 Difference
2025-06-07 15:25:51 -04:00
David Korth
5fd65dc7e2 [kde] AchQtDBus::notifyFunc(): Use QString::arg() for the text.
It's slightly less efficient than manually building the string, but
this lets us reformat the text more easily later on, if needed.

Code size differences: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
  14174      72       5   14251    37ab AchQtDBus.cpp.o [kf5] [before]
  14221      72       5   14298    37da AchQtDBus.cpp.o [kf5] [after]
    +47       0       0     +47     +2f Difference

   text    data     bss     dec     hex filename
  12995     200       5   13200    3390 AchQtDBus.cpp.o [kf6] [before]
  13164     200       5   13369    3439 AchQtDBus.cpp.o [kf6] [after]
   +169       0       0    +169     +a9 Difference
2025-06-07 15:20:22 -04:00
David Korth
50ae166484 [kde] RpQt.hpp: New function Q2U8_StdString().
On Qt5 and Qt6, QString::toStdString() converts the string to a UTF-8
std::string, so this simply wraps around that.

On Qt4, QString::toStdString() uses QString::toAscii(), so instead,
we use QString::toUtf8().constData() and convert that into an std::string.

This is more efficient when saving to an std::string, since Q2U8() only
returns the data pointer, which makes it an implicit-length C string.

Q2U8_StdString() is now used wherever an std::string needs to be saved.

Updated all other uses to use Q2U8() instead of QString::toUtf8().constData().

FIXME: RpFileKio::filename():
- Q2U8() returns a temporary, which may be gone by the time this function
  returns...

Code size differences: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
  30982    1648      48   32678    7fa6 kfilemetadata_rom-properties-kf5.so [before]
  30846    1648      48   32542    7f1e kfilemetadata_rom-properties-kf5.so [after]
   -136       0       0    -136     -88 Difference

   text    data     bss     dec     hex filename
  26844    1456      48   28348    6ebc overlayiconplugin_rom-properties-kf5.so [before]
  26726    1456      48   28230    6e46 overlayiconplugin_rom-properties-kf5.so [after]
   -118       0       0    -118     -76 Difference

   text    data     bss     dec     hex filename
 599947   21896      64  621907   97d53 rom-properties-kf5.so [before]
 600363   21896      64  622323   97ef3 rom-properties-kf5.so [after]
   +416       0       0    +416    +1a0 Difference

   text    data     bss     dec     hex filename
  55979    2824      48   58851    e5e3 RomThumbnailCreator-kf5.so [before]
  55795    2824      48   58667    e52b RomThumbnailCreator-kf5.so [after]
   -184       0       0    -184     -b8 Difference

   text    data     bss     dec     hex filename
  78593    5144      48   83785   14749 xattrview-kf5.so [before]
  78546    5152      48   83746   14722 xattrview-kf5.so [after]
    -47      +8       0     -39     -27 Difference

   text    data     bss     dec     hex filename
  33049    1760      48   34857    8829 kfilemetadata_rom-properties-kf6.so [before]
  32497    1752      48   34297    85f9 kfilemetadata_rom-properties-kf6.so [after]
   -552      -8       0    -560    -230 Difference

   text    data     bss     dec     hex filename
  28794    1584      48   30426    76da overlayiconplugin_rom-properties-kf6.so [before]
  28350    1568      48   29966    750e overlayiconplugin_rom-properties-kf6.so [after]
   -444     -16       0    -460    -1cc Difference

   text    data     bss     dec     hex filename
 595782   29168      80  625030   98986 rom-properties-kf6.so [before]
 595959   29176      80  625215   98a3f rom-properties-kf6.so [after]
   +177      +8       0    +185     +b9 Difference

   text    data     bss     dec     hex filename
  61854    3352      48   65254    fee6 RomThumbnailCreator-kf6.so [before]
  61649    3360      48   65057    fe21 RomThumbnailCreator-kf6.so [after]
   -205      +8       0    -197     -c5 Difference

   text    data     bss     dec     hex filename
  76033    6224      48   82305   14181 xattrview-kf6.so [before]
  75690    6216      48   81954   14022 xattrview-kf6.so [after]
   -343      -8       0    -351    -15f Difference
2025-06-07 15:15:42 -04:00
David Korth
6577715f73 [librpbase] APNG_dlopen.h: Don't export APNG_ref() and APNG_unref().
It's only used by librpbase internally.

This is technically an ABI break, even though these functions weren't
used outside of librpbase, so bump the SOVERSION to 7.
2025-06-07 14:38:47 -04:00
David Korth
2c17a8e727 [libgsvt] gsvt_win32.c: Clear bold and bright when setting "normal" intensity. (SGR 22) 2025-06-07 14:16:33 -04:00
David Korth
cff7086b3d [libromdata] CisoPspDlopen.cpp: Define PTHREAD_ONCE_INIT on Windows.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
2025-06-05 23:25:05 -04:00
David Korth
981c173142 [libromdata] CisoPspDlopen.hpp: Need to typedef int pthread_once_t on Windows.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
Normally this would be in pthread_once.h, but we're not using the
standard version due to calling a class member function.
2025-06-04 13:33:21 -04:00
David Korth
df719e959a [libromdata] CisoPspDlopen.hpp: Fix build warnings and errors in no-LZ4/no-LZO builds.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
NOTE: Disabling LZ4 and LZO entirely prevents the libraries from
being loaded at all. This currently results in CISOv2 images that
partially load, but fail when an LZ4-compressed block is encountered.
2025-06-04 10:48:41 -04:00
David Korth
3af7964b0c [librpthreads] pthread_once.c: Use sched_yield() for consistency.
Windows doesn't have either function. Instead, we end up calling
SwitchToThread().
2025-06-04 10:34:52 -04:00
David Korth
723712102a [libromdata] CisoPspDlopen: Use an implementation of pthread_once() to initialize the libraries.
We can't use standard pthread_once() here due to the use of member
functions. Instead, we're using a macro that simulates it, based on
the Windows version in pthread_once.c.

NOTE: Still using the standard pthread_once_t type, which is `long`
on Linux systems.

[librpthreads] CMakeLists.txt: Check for sched_yield().
pthread_yield() is deprecated as of glibc-2.34.

If sched_yield() isn't found, define it as pthread_yield().
2025-06-04 10:31:51 -04:00
David Korth
3416f16ad2 [libromdata] CisoPspDlopen: Remove some debugging printf()'s. 2025-06-04 10:13:46 -04:00
David Korth
3db391e8c1 [libromdata] CisoPspReader: Make the CisoPspDlopen object static.
This will make it so only one initialization is needed if using a single
libromdata.so load to read multiple PSP images.

NOTE: CisoPspDlopen isn't thread-safe at this point. Need to use
pthread_once() for initialization.
2025-06-04 10:12:37 -04:00
David Korth
4ab931b127 [libromdata] CMakeLists.txt: Bump the SOVERSION to 6.2.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
It's ABI-compatible with 6.0 and 6.1 (using only .so.6, not .so.6.2),
but there have been changes since the previous release.
2025-06-03 22:54:55 -04:00
David Korth
e1ef6e6d2f [libromdata] CisoPspDlopen: Split the dlopen() code from CisoPspreader into a separate class. 2025-06-03 22:54:42 -04:00
David Korth
e9625cb876 [libromdata] CisoPspReaderPrivate::init_pfn_LZO(): LZO, not LZ4. 2025-06-03 22:53:19 -04:00
David Korth
79c3a2e34d [libromdata] dlopen-notes.c: Add liblz4.so.1 and liblzo2.so.2 to the dlopen() notes section.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
2025-06-02 22:52:13 -04:00
David Korth
8650f2b1c2 [debian] control: Add liblz4-1 and liblzo2-2 as explicit dependencies to libromdata6.
These are now dlopen()'d, so ${shlibs:Depends} won't detect them.

NOTE: Newer versions of Debian tools might detect them if we add
dlopen() notes.
2025-06-02 22:43:12 -04:00
David Korth
e2f4ddde72 [libromdata] CisoPspReader: Dynamically load the LZO library using dlopen().
TODO: Keep the dlopen()'d libraries around for multiple uses?
May need to create a helper class...
2025-06-02 20:29:35 -04:00
David Korth
88a9a603ce [libromdata] CisoPspReader::CisoPspReader(): Missed a HAVE_LZ4. 2025-06-02 19:57:11 -04:00
David Korth
60b18c408f [libromdata] CisoPspReader: Dynamically load the LZ4 library using dlopen().
LZ4 is only used by CisoPspReader, so there's no need to load it on
startup on Linux systems. Instead, use dlopen().

Remove the various `#ifdef HAVE_LZ4` checks.

TODO: Show a warning if the image requires LZ4 but we don't have it.
For now, it just says the image couldn't be opened.

On Windows, we're switching from DelayLoad to LoadLibrary() for
consistency.

[libwin32common] DelayLoadHelper.h: Export rp_LoadLibrary().
This is used by CisoPspReader to load lz4.dll.

The exported version does not do a DLL whitelist check, whereas
the version used by the MSVC exception handler does.
2025-06-02 19:42:16 -04:00
David Korth
ed799a1cc2 [rp-download] rp-download.cpp: recvmmsg() is needed by cURL 8.13 for QUIC (HTTP/3).
Noticed this on my local system after updating from cURL 8.12 to 8.13:

$ /usr/libexec/rp-download -v sys/version.txt
URL: https://rpdb.gerbilsoft.com/sys/version.txt
Cache Filename: /home/user/.cache/rom-properties/sys/version.txt
Cache file for 'sys/version.txt' is already downloaded, but this cache key is set to download-if-newer.
SYSCALL TRAP: [amd64] recvmmsg()
Segmentation fault
2025-06-02 19:40:56 -04:00
David Korth
407fb36461 [libpng] Disable /guard:cf in MSVC builds for now.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
This is what was causing the libpng crash in png_longjmp() on
Windows 10 in MSVC 2022 release builds.

See #451: libpng errors crash due to libpng setjmp/longjmp (Windows 10, release builds only)
Reported by @Masamune3210.
2025-05-26 11:11:51 -04:00
David Korth
55fac18b76 [librptext/tests] TextFuncsTest: Add fourCC tests.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
For both the char* version and the std::string version.

Code coverage change:

Before:
  source files: 607
  lines.......: 24.1% (11442 of 47453 lines)
  functions...: 24.0% (910 of 3786 functions)
  branches....: 17.0% (8352 of 49177 branches)

After:
  source files: 607
  lines.......: 24.1% (11450 of 47453 lines)
  functions...: 24.1% (911 of 3786 functions)
  branches....: 17.0% (8353 of 49177 branches)
2025-05-25 16:08:03 -04:00
David Korth
440bb7aeb5 Increase minimum CMake versions to "3.5...3.10".
CMake 4.0 drops compatibility with versions older than 3.5, and warns
that compatibility with < 3.10 will be dropped in a "future version".

CMake 3.30 previously warned about dropping support for older than
3.5, which was changed in 3.31 to older than 3.10.
2025-05-25 15:39:40 -04:00
David Korth
c0c8b2582c CMakeLists.txt: Enable policy CMP0177 if it's available.
This fixes a bunch of warnings similar to the following:

CMake Warning (dev) at src/kde/kf5/CMakeLists.txt:370 (INSTALL):
  Policy CMP0177 is not set: install() DESTINATION paths are normalized.  Run
  "cmake --help-policy CMP0177" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.
This warning is for project developers.  Use -Wno-dev to suppress it.
2025-05-25 15:29:54 -04:00
David Korth
7e51a47609 [libromdata] NES: Some FDS images have Heisei era years, starting at 01.
Assume anything <=57 is Heisei, and >=58 (1983) is Shōwa.

NOTE: The FDS was released in 1986, but we'll allow for 1983 just in case
there was an FDS game in development in 1985. (Maybe the lower bound
should be 1985 instead...)
2025-05-25 15:26:01 -04:00
David Korth
b72bd8a436 [extlib] Skip installation of binaries for minizip-ng.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
FIXME: The minigzip and minizip binaries are automatically built,
even though we use SET_EXTLIB_PROPERTIES(), which should exclude
them from ALL builds...
2025-05-25 00:35:04 -04:00
David Korth
7d6c7064d2 [libromdata] Xbox360_STFS_Private::getTitle(): Remove mojibake_chars.
I was originally going to use a lookup table, but decided to use
switch/case instead. I never removed the lookup table, though...
2025-05-24 15:13:05 -04:00
David Korth
065c86149a NEWS.md: Update the Xbox360_STFS mojibake description.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
2025-05-24 15:08:28 -04:00
David Korth
32ac318236 [libromdata] Xbox360_STFS_Private::getTitle(): It's all UTF-8.
The Shift-JIS thing was incorrect, even with the U+0081 code point.
It's all UTF-8 that was incorrectly converted from cp1252 to UTF-16BE.

Also, remove a redundant string conversion that I was using earlier for
debugging purposes and is no longer needed.
2025-05-24 15:06:47 -04:00
David Korth
5de651dbbe [libromdata] Xbox360_STFS: Fix titles for some packages that were authored incorrectly and have mojibake titles.
Two types of mojibake are detected and fixed:
- UTF-8 parsed as cp1252
- Shift-JIS parsed as cp1252

For the latter case, utf16_to_cp1252() on Linux (and other systems that
use iconv) has been modified to handle five code points that iconv()
doesn't support: 0x81, 0x8D, 0x8F, 0x90, 0x9D.

TODO: Also do this for utf8_to_cp1252() and other cp1252 functions?

On Windows, WideCharToMultiByte() and MultiByteToWideChar() handle these
code points without any issues.

These three title updates now show a correct title:

TU_11LK1UV_0000004000000.0000000000081 (UTF-8 as cp1252)
Name:  'Dodonpachi Daifukkatsu Black Label Title Update #1'
Title: '怒首領蜂 大復活 Black Label'

TU_12501VG_0000004000000.0000000000101 (UTF-8 as cp1252)
Name:  'DREAM C CLUB Title Update #4'
Title: 'ドリームクラブ'

TU_15LG1UH_000000C000000.0000000000083 (Shift-JIS as cp1252)
Name:  'Circle of Students Title Update #1'
Title: '円卓の生徒'

Fixes #450: X360 - Non-Latin Titles appearing as mojibake
Reported by @Masamune3210.
2025-05-24 15:02:21 -04:00
David Korth
34f76050cb [librpbase] RpPng: Work around a potential libpng crash when attempting to read empty data as a PNG image.
Check the magic number before initializing libpng.

It seems there's something wrong with MSVC 2022 (17.6.5) that causes a
release build of libpng to crash when calling longjmp() on Windows 10.

If this is in fact a compiler bug, and upgrading the compiler fixes it,
then I'll need to switch away from my Windows 7 VM because MSVC 17.6 is
the last version to support Windows 7 as a build environment.

See #451: libpng errors crash due to libpng setjmp/longjmp (Windows 10, release builds only)
Reported by @Masamune3210.
2025-05-24 13:53:47 -04:00
David Korth
223cee6c9c [librpbase/tests, libromdata/tests] Hexdumps: Add an extra space after the offset. 2025-05-22 23:49:10 -04:00
David Korth
fc44e1da01 [librptext] formatFileSize(): TODO: Have the UI frontend set the "default" dialect, e.g. using kdeglobals on KDE.
For now, defaulting to IEC. (Same as before, but now more explicit.)
2025-05-22 18:29:28 -04:00
David Korth
7c96eb5381 [libgsvt] gsvt_win32.c: Fix vt->bold initialization.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
2025-05-20 21:34:40 -04:00
David Korth
54a7b12523 [libgsvt] gsvt_win32_console_print_ANSI_emulate(): xterm supports BEL (\007) in addition to ST for ending an OSC sequence.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
2025-05-17 14:42:04 -04:00
David Korth
443df8a7ab [libgsvt] gsvt_init_win32(): Set bold if the initial attributes have FOREGROUND_INTENSITY set. 2025-05-17 14:39:42 -04:00
David Korth
86638f478c [xdg] rom-properties.xml: Add GameCube/Wii executables (.dol).
.dol files aren't currently supported by rom-properties. shared-mime-info
is misidentifying them as image/vnd.microsoft.icon, which is clearly
wrong, so add this to fix the identification.
2025-05-17 14:36:18 -04:00
David Korth
55cb219a17 [rp-download] Set an "Accept:" header for the expected MIME type.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
Expected MIME types:
- .png: image/png
- .jpg: image/jpeg
- .txt: text/plain

Not sure if this will make any real difference, but we might as well
set it anyway.
2025-05-17 13:17:45 -04:00
David Korth
05f08c2d32 [librpbyteswap] byteswap_rp.h: Can't mark __swabf() as constexpr on MSVC.
__swab32(), aka _byteswap_ulong(), is *still* not constexpr on MSVC.
2025-05-17 13:02:38 -04:00
David Korth
8e841026e9 [minizip-ng] CMakeLists.txt: Don't check for ZLIB/ZLIBNG.
zlib is already checked earlier. On my system, since I have zlib-ng
installed system-wide, this check picks it up, and causes libromdata.so.6
to be linked to libz-ng.so.2.

Disabling the check removes that linkage.

NOTE: The Ubuntu packages for 2.5 and 2.5.1 are *not* linked to zlib-ng,
since Ubuntu doesn't have zlib-ng included by default.

Also, update _MODIFIED_MINIZIP.txt for 4.0.10. (Forgot to do this when
updating from 4.0.9 to 4.0.10.)
2025-05-13 22:47:38 -04:00
David Korth
46c83d92c1 Rework CONSTEXPR_IF_MSVC2022 into CONSTEXPR_MULTILINE and CONSTEXPR_MULTILINE_NO_MSVC.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
gcc-4.9 on Debian 8 doesn't support multi-line constexpr functions.

CONSTEXPR_MULTILINE enables constexpr for MSVC 2022 and gcc-5,
and later versions.

CONSTEXPR_MULTILINE_NO_MSVC enables constexpr for gcc-5 and later,
but not MSVC. Needed for functions that use intrinsics, which
(still) aren't marked as constexpr on MSVC.
2025-05-12 21:34:55 -04:00
David Korth
44eba93a3e Remove some old FIXMEs and TODOs.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
2025-05-11 12:35:38 -04:00
David Korth
ade40a4965 [libromdata] IntellivisionPrivate::getTitle(): Handle characters 0x3E and 0x3F correctly.
These correspond to U+2191 UPWARDS ARROW and U+2190 LEFTWARDS ARROW,
respectively.
2025-05-11 11:46:03 -04:00
David Korth
0f2eccd3ac [librptexture] ImageSizeCalc.hpp, validateBlockSizeASTC(): Rework into a single-line constexpr() function.
Remove the assertions, since they aren't very useful. They'd only assert
if the file is corrupted.

TODO: Validate combinations?
2025-05-11 11:21:24 -04:00
David Korth
99942e6a04 rp-libfmt.h: Add a to_tstring() macro.
NOTE: `using` statements within `namespace fmt` didn't work:
src\rp-libfmt.h(48,21): error C2061: syntax error: identifier 'to_wstring'

[win32] RomDataFormat.cpp, ImageTypesTab.cpp: Use fmt::to_tstring().
2025-05-11 11:11:10 -04:00
David Korth
1912c62551 [libromdata/tests] GcnFstPrint, WiiUFstPrint: Add colorization for error and warning messages. 2025-05-11 11:04:32 -04:00
David Korth
43a7bd4a49 [libromdata/tests] GcnFstPrint, WiiUFstPrint: Use libgsvt.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
The Unicode text printing on Windows via _fputts() was causing the
console output to lock up on Windows 7. Switching to libgsvt fixes it.

Code size difference: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
  16247    1032      48   17327    43af GcnFstPrint [before]
  19006    1160      80   20246    4f16 GcnFstPrint [after]
  +2759    +128     +32   +2919    +b67 Difference

   text    data     bss     dec     hex filename
  15417    1016      48   16481    4061 WiiUFstPrint [before]
  18210    1144      80   19434    4bea WiiUFstPrint [after]
  +2793    +128     +32   +2953    +b89 Difference
2025-05-11 04:13:24 -04:00
David Korth
665a9f878c [locale] fr.po: Translate Ext2AttrView's placeholders by adding a space before the colon. 2025-05-11 03:47:23 -04:00
David Korth
94470e319a [kde] Use QC_() for translation, not QObjectDerivedClass::tr().
The xgettext call in locale/CMakeLists.txt doesn't detect
QObjectDerivedClass::tr(). Because of this, we ended up missing
a few strings for translation.

[locale] Update with the missed strings.
2025-05-11 03:46:48 -04:00
David Korth
9a5550f1f5 [locale] Update rom-properties.pot and *.po.
Forgot to do this for the v2.5.1 release...
2025-05-11 03:39:18 -04:00
David Korth
f13bde810f [librptexture] ImageDecoder::fromLinear32_ssse3(): Missed a 16-byte stride alignment check.
xtexconv includes a sample DDS that has stride == 15,076. Without this
check, rpcli crashes due to the use of movdqa on an unaligned pointer.

Reference: https://learn.microsoft.com/en-us/samples/microsoft/xbox-gdk-samples/xtexconv/
2025-05-11 03:20:44 -04:00
David Korth
f6d9394da8 [libgsvt] gsvt_win32.c, gsvt_win32_console_print_ANSI_emulate(): RESET command should update bold.
`bold` should be set to true if wAttributes has FOREGROUND_INTENSITY.
2025-05-11 02:36:16 -04:00
David Korth
a83c05459d [libgsvt] gsvt_win32.c: Get rid of an unnecessary #ifdef _WIN32. 2025-05-11 02:33:59 -04:00
David Korth
18b7ec55d3 [libgsvt] gsvtpp.cpp: Remove the struct _gsvt_console definition.
I added this here for testing purposes in order to verify that the
consoles were initialized properly. It isn't needed here anymore.
2025-05-11 01:22:49 -04:00
David Korth
53648f1ffa Merge branch 'feature/libgsvt' 2025-05-11 01:18:23 -04:00
David Korth
03df42456c Multi-line constexpr functions are only supported as of MSVC 2022.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
New macros:
- CONSTEXPR_IF_MSVC2022: constexpr for MSVC 2022 and later (also gcc).
- CONSTEXPR_NO_MSVC: no constexpr on any MSVC (but yes on gcc).

Use CONSTEXPR_IF_MSVC2022 on multi-line constexpr functions.

Use CONSTEXPR_NO_MSVC on functions that can be constexpr on gcc but
not any version of MSVC.
2025-05-11 00:58:11 -04:00
David Korth
d241d33537 NEWS.md: Mention more rpcli colorization and libgsvt refactoring. 2025-05-11 00:44:33 -04:00
David Korth
e495796ee8 [rpcli] verifykeys.cpp: Missed a gsvt_fputs() conversion.
Code size difference: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
  45968    2176     416   48560    bdb0 rpcli [before]
  45904    2176     416   48496    bd70 rpcli [after]
    -64       0       0     -64     -40 Difference
2025-05-11 00:41:31 -04:00
David Korth
e81f24cc39 [libgsvt] Added a gsvt_fflush() wrapper function.
Also Gsvt::Console::fflush().

[rpcli] rpcli.cpp, verifykeys.cpp: Use Gsvt::Console::fflush().

verifykeys.cpp: Only call fflush() at the end of the function.

Code size difference: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
  45929    2168     432   48529    bd91 rpcli [before]
  45968    2176     416   48560    bdb0 rpcli [after]
    -39      +8     -16     -31     -1f Difference
2025-05-11 00:37:08 -04:00
David Korth
381980d13e [libgsvt] gsvtpp: New C++ wrapper class.
Gsvt::StdOut and Gsvt::StdErr are predefined as wrappers around
gsvt_stdout and gsvt_stderr.

Accessing either of the wrapper classes automatically calls gsvt_init().

gsvt_posix.c, gsvt_win32.c: Rework gsvt_init() to use pthread_once() so
multiple initializations won't cause problems.

[rpcli] rpcli.cpp, verifykeys.cpp: Use gsvtpp.

This does increase the code size a tiny bit...

Code size difference: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
  45810    2152     416   48378    bcfa rpcli [before]
  45929    2168     432   48529    bd91 rpcli [after]
   +119     +16     +16    +151     +97 Difference
2025-05-11 00:30:53 -04:00
David Korth
23f71c4f9c [rpcli] rpcli.cpp: Use the C++ string version of gsvt_fputs() on Windows.
This function calls gsvt_write() internally.
2025-05-11 00:15:51 -04:00
David Korth
78da45fb5d [rpcli] rpcli.cpp: Colorize more warnings. 2025-05-10 23:44:02 -04:00
David Korth
f2c3b6c5ba [rpcli] rpcli.cpp: Improve language code handling.
- Convert the language code from uppercase to lowercase.

- After the conversion, make sure that the language code is all
  lowercase characters.

- Colorize the warning message in yellow.

ctypex.h:

- Use `int` instead of `char` in the non-localized functions. This
  ensures Windows TCHAR works properly without getting truncated.

- New functions toupper_ascii() and tolower_ascii().
2025-05-10 23:27:36 -04:00
David Korth
d5ede2ee5b [rpcli] Remove vt.cpp.
libgsvt now has all of its functionality.
2025-05-10 23:07:28 -04:00
David Korth
23c473e5e3 [rpcli] verifykeys.cpp: Update to use libgsvt instead of rpcli's vt.hpp. 2025-05-10 23:05:47 -04:00
David Korth
1f856117ec Move Win32 console output code page handling from rpcli.cpp to libgsvt/gsvt_win32.c. 2025-05-10 23:05:47 -04:00
David Korth
3efdc825d9 [libgsvt] Optimize gsvt_text_color_set8().
- POSIX: Use fprintf().
- Win32: Use WriteConsoleA() if it's a real console.
2025-05-10 23:05:47 -04:00
David Korth
611fea3782 [libgsvt] gsvt_win32.c: Windows implementation.
Mostly copied from rpcli's vt.cpp, but with a few changes. In particular:

- gsvt_fwrite() and gsvt_fputs() are wrappers around the ANSI emulation
  code, *if* ANSI isn't supported and it's a real console.

- The ANSI emulation code no longer resets attributes after data is
  written, since we might make multiple calls with color changes.

[rpcli] rpcli.cpp: Simplify the Windows-specific code.

Instead of checking if the console is a console, just use gsvt_fwrite().
gsvt_fwrite() will handle this.

FIXME: gsvt_cout wrapper so we can get rid of this.
2025-05-10 23:05:47 -04:00
David Korth
44608520b8 Initial refactoring of rpcli's VT code into a separate library.
Currently for Linux only. The Linux implementation is mostly just
wrapper functions around stdio.

gsvt_fputs() does not have a `newline` parameter, so anything that
used ConsolePrint()'s `newline` parameter now has to explicitly
call gsvt_newline().
2025-05-10 23:05:47 -04:00
David Korth
0328879a01 [rpcli] verifykeys.cpp: Remove some extra newlines.
Forgot to remove these when colorizing warning messages in
commit 365a7d5302.
([rpcli] verifykeys.cpp: Colorize output.)

Affects: v2.5.1
2025-05-10 23:05:47 -04:00
David Korth
53b74e0467 [debian] rules: Explicitly specify the Tracker API version, again.
Otherwise, we have to install the specific Tracker library, which is
versioned, so we end up with more problems.

(cherry picked from commit 1356d23d4c)
2025-05-10 21:04:30 -04:00
David Korth
c632a35c62 Version bump for development. (v2.5.1+) 2025-05-10 21:04:16 -04:00
David Korth
1f246e4ff6 rom-properties 2.5.1 2025-05-10 16:41:45 -04:00
David Korth
f5334daa78 [kde] Ext2AttrView: Use QString::arg() instead of fmt::format().
fmt::format() worked on my main system, but on Xubuntu 16.04, it didn't
work because the fmt headers aren't included:

src/kde/xattr/Ext2AttrView.cpp: In member function ‘void Ext2AttrViewPrivate::retranslateUi_nonDesigner()’:
src/kde/xattr/Ext2AttrView.cpp:94:13: error: ‘fmt’ has not been declared
   s_label = fmt::format(FRUN(s_lsattr_fmt), p->lsattr_chr,
             ^
src/kde/xattr/Ext2AttrView.cpp:94:42: error: ‘FRUN’ was not declared in this scope
   s_label = fmt::format(FRUN(s_lsattr_fmt), p->lsattr_chr,
                                          ^

We're not linking to fmt in the XAttrView plugin, so use QString::arg()
instead. (I'm guessing CMake auto-magically linked to fmt because
libromdata links to it...)

NOTE: The debug build still links to libfmt-11.so (and a bunch of other
libraries that aren't actually needed). The release build no longer links
to libfmt-11.so. I'm guessing CMake is skipping .so trimming in the debug
builds in order to save time.
2025-05-10 16:19:20 -04:00
David Korth
9d50275042 [libromdata] GameCubeSavePrivate::PDP_SWAP(): Initialize the union to 0.
This doesn't affect the compiled output, but it's needed by gcc-5.4
in order to be marked as constexpr.

The uninitialized union *is* allowed as of C++20, supported in
gcc-10.1 and later.

Also, put 'd' first so the whole DWORD is initialized instead of just
one 16-bit WORD.
2025-05-10 15:50:35 -04:00
David Korth
8c00596598 [librptexture] ImageDecoder_BC7.cpp, get_mode(): Remove constexpr.
assert() isn't constexpr-safe on Ubuntu 16.04. (glibc-2.23)
2025-05-10 15:16:18 -04:00
David Korth
7efa014ba8 [librpbyteswap] byteswap_rp.h, __swabf(): Initialize the union to 0.
This doesn't affect the compiled output, but it's needed by gcc-5.4
in order to be marked as constexpr.

The uninitialized union *is* allowed as of C++20, supported in
gcc-10.1 and later.
2025-05-10 15:09:57 -04:00
David Korth
3d0fd3627b [librptexture] PixelConversion.hpp: Remove constexpr for RGB9_E5_to_ARGB32().
MSVC 2022 doesn't like it, and apparently gcc-13.2.1 didn't like it.
(gcc-15.1.0 is fine with it, though...)
2025-05-10 14:54:13 -04:00
David Korth
9e2aff3d1a Undo some constexpr for MSVC.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
MSVC's byteswapping intrinsics are not constexpr.
2025-05-10 14:45:49 -04:00
David Korth
05e95ec9a8 [libromdata] Xbox360_XEX_Private::getOptHdrData(): Limit the maximum header size to 16 MB.
aflplusplus, and the debug version of rpcli, was hanging on some fuzzed
XEXes with ~4 GB headers because the debug version of std::vector<> was
initializing each byte, one at a time.

Headers shouldn't be that big, but we'll go with a maximum of 16 MB
just in case.

Found using aflplusplus-4.32c.
2025-05-10 14:16:25 -04:00
David Korth
4a85bc7be4 Added constexpr to a bunch of static inline functions.
[libromdata]
- SNES, isValidGameIDChar(): Use the is*_ascii() functions.
- DMG: Remove `inline` from some functions.
- GcnFst, WiiUFst: Completely inline the is_dir() functions.

[librpbase]
- cdrom_structs.h: Add CONSTEXPR; make CdromSectorInfo extern "C".
- RpPngWriter: Remove `inline` from u8strIsPngLatin1().

[librpbyteswap]
- bitstuff.h: CONSTEXPR and ATTR_CONST stuff.
- byteswap_rp.h: Likewise.

[librptexture]
- XboxXPR: Fully inline and constexpr fill_pattern() and
  get_swizzled_offset().

The inlining and constexpr for XboxXPR does reduce the code size
slightly:

Code size difference: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
   8336    1208       0    9544    2548 XboxXPR.cpp.o [before]
   8240    1208       0    9448    24e8 XboxXPR.cpp.o [after]
    -96       0       0     -96     -60 Difference
2025-05-10 13:26:36 -04:00
David Korth
ae3dd69c78 [librptext] conversion_iconv.cpp: codePageToEncName(): Return an std::string.
This cleans up the code a bit, but does increase the .o size due to the
use of std::string.

Code size difference: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
   6898       8       0    6906    1afa conversion_iconv.cpp.o [before]
   9780       8       0    9788    263c conversion_iconv.cpp.o [after]
  +2882       0       0   +2882    +b42 Difference
2025-05-10 13:18:05 -04:00
David Korth
b32ddb101e [librptexture] qoi.h: Update to latest git master release.
Upstream commit message:

Merge pull request #319 from DeeJayLSP/modulo

Make encoding 1.4% faster by replacing modulo with mask
2025-05-10 12:48:06 -04:00
David Korth
d58918f101 [rpcli] rpcli.cpp: Fix two errors introduced since switching over to vt.cpp.
- DoFile(): JSON errors should be printed to stdout, not stderr.

- _tmain(): Remove an extra newline after the `default:` case's
  "skipping unknown switch" message.
2025-05-10 12:46:07 -04:00
David Korth
25c5aa02cc [minizip] Update: v4.0.9 -> v4.0.10
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
CMakeLists.txt: Add a missing "LINKER_LANGUAGE C". Not entirely sure
when this was added, or why I missed it...
2025-05-06 18:49:33 -04:00
David Korth
29aa2dacc9 [librpbase] TextOut_text.cpp, formatDateTime(): Use localtime_r() instead of fmt::localtime().
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
Interestingly, this didn't print any warnings or errors on gcc, but on
MSVC, this warning was produced:

src\librpbase\TextOut_text.cpp(359,20): error C2220: the following warning is treated as an error
src\librpbase\TextOut_text.cpp(359,20): warning C4996: 'fmt::v11::localtime': was declared deprecated
2025-05-04 20:33:27 -04:00
David Korth
10785d08fb Revert "time_r.h: Remove gmtime_r() and localtime_r() wrappers."
fmt-11.2.0 deprecated fmt::localtime(), so we'll need to bring back
our localtime_r() wrapper.

This reverts commit 137a7c0f5f.
2025-05-04 20:07:50 -04:00
David Korth
c66cd83539 [fmt] Update: v11.1.4 -> v11.2.0 2025-05-04 20:07:29 -04:00
David Korth
425f5a77e4 [libromdata] Nintendo3DSPrivate: Reduce headers_loaded from uint32_t to uint8_t.
Only 5 bits are currently used, and this reduces padding due to 64-bit
alignment in the mxh union.

Total struct size before: 9,176
Total struct size after:  9,168
Difference:                  -8
2025-05-04 12:51:20 -04:00
David Korth
050380db45 ctypex.h: Add is*_ascii() functions.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
These functions do non-localized checks, which improves performance in
most cases (due to not need to do locale lookups) and is more "correct"
when checking ROM headers in most cases.

[rpcli] vt.cpp: Removed vt_isdigit() and vt_isalpha(). We can use
isdigit_ascii() and isalpha_ascii() instead.

[libromdata] Updated most IS*() uses to is*_ascii().
NOTE: ISPRINT() and ISSPACE() are left as-is for now.

VirtualBoy: We can mark all of the private is*() functions as
constexpr now.
2025-05-04 12:45:15 -04:00
David Korth
b4ba027439 [libpng] Forgot to check in new file PNGCheckLibconf.cmake.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
2025-05-03 20:18:22 -04:00
David Korth
66e75f5a40 [libromdata] WiiTicketPrivate::getEncKey(): Use a lookup table for the CA/XS combinations.
Code size difference: (64-bit Gentoo Linux, gcc-15.1.0, release build, no LTO)

   text    data     bss     dec     hex filename
   8077     808       0    8885    22b5 WiiTicket.cpp.o [before]
   8029     808       0    8837    2285 WiiTicket.cpp.o [after]
    -48       0       0     -48     -30 Difference
2025-05-03 19:15:14 -04:00
David Korth
e804c1236f NEWS.md: Mention vWii packages. 2025-05-03 19:03:00 -04:00
David Korth
91e4a39eb1 [libromdata] WiiUPackage: Don't attempt to access Wii U-specific TMD or FST stuff in vWii packages.
vWii packages use v0 tickets and TMDs. The "content groups" doesn't
exist, nor does the FST, the system XMLs, or the TGA icons.

Skip all of these if a v0 TMD is detected.

TODO: Change the system name for v0?
2025-05-03 19:01:54 -04:00
David Korth
cbbe2e1a3d [libromdata] WiiTicket::isRomSupported_static(): Allow larger tickets for vWii titles.
NUS vWii titles may have a certificate chain appended to the ticket.
2025-05-03 19:01:26 -04:00
David Korth
85e9ca4fad [rpcli] vt.cpp: win32_color_map is only used on Windows. 2025-05-03 11:31:50 -04:00
David Korth
a077d26d67 [rpcli] vt.cpp, ConsoleSetTextColor(): Combine the two snprintf() calls into one. 2025-05-03 10:59:17 -04:00
David Korth
c706f7ba9b [libpng] Update: v1.6.47 -> v1.6.48
The APNG patch for v1.6.48 isn't out yet, but unlike v1.6.47, this
release doesn't have any major breaking changes.
2025-05-03 10:23:59 -04:00
David Korth
e07a45be0e NEWS.md: Mention URL colorization and "OSC 8" markup. 2025-05-03 09:45:59 -04:00
David Korth
45e049168e Merge branch 'feature/xattr-compression-algorithm'
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
2025-05-03 09:44:46 -04:00
David Korth
6056d61f2c NEWS.md: Mention xattr compression algorithms.
Some checks failed
Codecov / run (push) Has been cancelled
2025-05-03 09:44:05 -04:00
David Korth
21cc92b9c6 [librpfile] XAttrReader_p.hpp: Use bitflags instead of bools for all the "has*" variables.
std::bitset<> would also work, but the minimum size of std::bitset<> is
`unsigned long`, so it'd take up 8 bytes.
2025-05-02 23:19:58 -04:00
David Korth
594f379fe3 [librpfile] XAttrReader::hasXfsAttributes(): Fix typo; should return d->hasXfsAttributes, not d->hasExt2Attributes.
Not sure if this caused any weird issues...
2025-05-02 23:12:30 -04:00
David Korth
4c944a2add [gtk] Ext2AttrView: Fix alignment of lblCompression on GTK4.
Needed to enable hexpand and set xalign.

Not sure if this is needed or supported on GTK2 or GTK3, but using
gtk_box_pack_end() seems to work on the older versions anyway.
2025-05-02 21:38:52 -04:00
David Korth
88b9552cca [gtk] Ext2AttrView: Display the compression algorithm, if available.
XAttrView: Set the compression algorithm in Ext2AttrView.

We're using Ext2AttrView because most Linux file systems that support
compression also support Ext2-style attributes.
2025-05-02 21:34:37 -04:00
David Korth
6a425154a2 [kde] Ext2AttrViewPrivate::updateZAlgorithmLabel(): Remove a line of debugging code. 2025-05-02 21:22:44 -04:00
David Korth
dd75ff80ca [kde] Ext2AttrView: Revert the updateDisplay() change. [back to updateFlagsDisplay()]
This function is *only* used for flags. Not the compression algorithm.
2025-05-02 21:22:04 -04:00
David Korth
c9588a89f7 [gtk] Rename Ext2AttrView.c to Ext2AttrView.cpp.
XAttrReader::ZAlgorithm needs C++.
2025-05-02 21:18:10 -04:00
David Korth
147f9c745d [librpfile] XAttrReader: Rename the "compressionAlgorithm" stuff to "zAlgorithm".
[kde,win32] Update for this change.
2025-05-02 21:10:41 -04:00
David Korth
bca1c48b59 [librpfile] XAttrReader_posix.cpp: Remove some compression algorithm debugging code. 2025-05-02 21:06:46 -04:00
David Korth
ce01475b3d [kde] Ext2AttrView: Add a way to display the compression algorithm.
Named "zAlgorithm"; will rename the XAttrReader functions next.

XAttrView: Set the compression algorithm in Ext2AttrView.

We're using Ext2AttrView because most Linux file systems that support
compression also support Ext2-style attributes.
2025-05-02 21:04:13 -04:00
David Korth
2982457dcc [librpfile] XAttrReader_posix.cpp: Get the compression algorithm on btrfs file systems.
This is stored in the "btrfs.compression" extended attribute.

TODO: Add a wrapper function for reading xattrs.
2025-05-02 21:03:40 -04:00
David Korth
1e094fdb8e [gtk] _RpDragImageCxx ctor: Initialize pngBytes to nullptr.
When testing non-RomData files with `rp-stub -R`, I got random crashes.
gdb traced it back to an invalid g_bytes_unref() due to pngBytes not
being initialized properly.

This only affects the GTK4 version.

This fixes a regression from commit bc32b0c3a2.
([gtk] DragImage: Implement GTK4 drag & drop.)

Affects: v2.4 - v2.5
2025-05-02 21:02:59 -04:00
David Korth
1875c9da7e [win32] rp-*.rc: Update IDD_XATTRVIEW in the other languages.
rp-ru_RU.rc: There's now three rows in MS-DOS Attributes.
2025-05-02 20:19:56 -04:00
David Korth
b080caa4bf [win32] rp-en_US.rc: Minor adjustment to the compression algorithm dropdown. 2025-05-02 20:19:37 -04:00
David Korth
9f03ee8d45 [librpfile] XAttrReader: Initial "compression algorithm" function.
If supported, this will get the compression algorithm in use for
the specified file.

Currently, this is only implemented on Windows for both the read
functionality and the display functionality.

Regular NTFS compression uses LZNT1 and is indicated by the presence
of FILE_ATTRIBUTE_COMPRESSED.

Newer compression formats were added in Windows 10:
- XPRESS4K
- LZX
- XPRESS8K
- XPRESS16K

These do *not* set FILE_ATTRIBUTE_COMPRESSED, but for our purposes,
if one of these is set, the "Compressed" box will be checked.

A dropdown is shown that lists the current compression algorithm,
and all other algorithms. This might be changed to just a label
display later, unless I actually add the ability to change it later...
2025-05-02 19:48:44 -04:00
David Korth
d4b1693c49 [librpfile] XAttrReader: Un-indent the public and private class declarations. 2025-05-02 19:45:03 -04:00
David Korth
6f9f6b9cff [librpfile] FileSystem_win32.cpp, filesize_int(): Check for INVALID_HANDLE_VALUE. 2025-05-02 19:32:13 -04:00
David Korth
e9dcd3f131 [rpcli] vt.cpp, win32_console_print_ansi_color(): Get the console handle from ci_stdout.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
2025-05-01 22:45:43 -04:00
David Korth
917f0a497a [rpcli] vt.cpp: Skip "CSI 38 m" and "CSI 48 m".
These are used for truecolor and 256-color formatting, which aren't
supported by the old Windows console. Skip the extra parameters so
they don't cause problems:

- truecolor (2): skip 3 extra parameters
- 256-color (5): skip 1 extra parameter

This required switching from a range-based `for` loop to a regular
index-based `for` loop, since we can't adjust the counter in a
range-based `for` loop.
2025-05-01 22:33:22 -04:00
David Korth
6e80ad584a [rpcli] vt.cpp: Empty parameters (e.g. ";;") are handled as 0.
Initialize num to 0, and reset it to 0 instead of -1.

Remove the explicit params.empty() check, since it will always have at
least one parameter. ("ESC m" will nd up having a single 0 parameter.)
2025-05-01 22:19:45 -04:00
David Korth
836985e6ed [rpcli] vt.cpp: Don't bother checking for 0x9C as an equivalent to "ST".
The ANSI standard says C1 control codes are equivalent, but UTF-8 makes
these take up two bytes, and nothing actually uses them nowadays.
2025-05-01 22:08:10 -04:00
David Korth
2386a99cf3 [rpcli] rpcli.cpp: Add an (undocumented) option to force-enable ANSI color: -C
Tested on Windows 10 and it seems to work for both console output and
redirected file output. Need to test on Linux, Windows XP, and Windows 7.
2025-05-01 22:03:57 -04:00
David Korth
ff63ed7ec9 [rpcli] vt.cpp: Add custom non-localized vt_isdigit() and vt_isalpha() functions.
isdigit() is defined as non-localized in C++, but isalpha() is not.

For consistency, define both here. This ensures that *only* the specified
characters are handled as digit or command characters, whereas the
localized versions might accept some other characters.

It's also slightly faster, since it doesn't have to do any localization
checks. Both gcc and MSVC compile vt_isdigit() to a subtract-and-compare.
gcc compiles vt_isalpha() to an AND, subtract, and compare; MSVC ends up
generating a few subtract-and-compares. (clang has the same behavior as
gcc in this case, though the generated code is slightly different.)
2025-05-01 20:26:12 -04:00
David Korth
6213569763 [rpcli] vt.cpp: Simplify "CSI n X" processing by parsing parameters first, *then* applying them.
This will allow us to implement other "CSI" escape sequences later,
if needed. It also simplifies parsing in general, since, among other
things, we won't start to apply attributes until we know that the
"CSI" command in question is "m" (SGR, Select Graphic Rendition).
2025-05-01 20:16:49 -04:00
David Korth
2566f1302a [librpbase] TextOut_text.cpp, htmlLinkToOsc8(): Make OSC 8 the outer formatting.
Needed for Windows Terminal, and possibly others.
2025-05-01 20:00:36 -04:00
David Korth
d258332227 [librpbase] TextOut_text.cpp: extURL processing: OSC 8 needs to be *outside* of formatting in order to get Windows Terminal to recognize it.
Also, combine the separate sequences into larger strings as a minor
optimization.
2025-05-01 19:58:35 -04:00
David Korth
20b994cc99 [rpcli] vt.cpp, win32_console_print_ansi_color(): Don't apply attributes if the "CSI n" sequence ends with something other than "m".
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
We're not supporting other sequences right now, e.g. "CSI n A" for
Cursor Up, but those would otherwise have been applied as attributes,
even though they don't end with "m".

TODO: If we do implement other "CSI n" sequences, we'll need to search
for the terminator before parsing the attributes.
2025-04-29 23:15:09 -04:00
David Korth
59cb37c893 [librpbase] TextOut_text.cpp: Colorize and use "OSC 8" for links in STRF_CREDITS fields.
StringField: New function htmlLinkToOsc8() to convert an HTML link
to OSC 8. The link must be in the following format:

<a href="https://blahblahblah">description</a>

STRF_CREDITS fields are generated by the RomData subclass and not taken
from the ROM file, so this should be consistent. Currently, only one
RomData subclass actually uses STRF_CREDITS: Amiibo

SafeString: Change `bool quotes` to `SafeStringFlags flags`. This contains
two flags: SSF_QUOTES and SSF_NO_ESCAPE. SSF_NO_ESCAPE is used for the
STRF_CREDITS field if using htmlLinkToOsc8(). Again, these fields should
not have weird control codes, since they're generated by the RomData
subclass, not taken from the ROM file.

Konsole seems to recognize "amiibo.life" as a link with the OSC 8 markup,
but not without it, so it seems it *is* working.

NOTE: The HTML link is left as-is if not converting to ANSI escapes.
Maybe it should be processed... (The RomHeaderTest results for Amiibo
would need to be updated in that case.)
2025-04-29 21:10:50 -04:00
David Korth
3a318c5924 [librpbase] TextOut_text.cpp: Use "OSC 8" to indicate hyperlinks.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
Not all terminal emulators support it. KDE Konsole is listed as
supported, but it doesn't seem to be working here... Need to test
it on other supported terminal emulators.

At the very least, it doesn't cause anything to look *different*
if it's enabled and the terminal emulator doesn't support it.

[rpcli] vt.cpp: Ignore "OSC" sequences, since we can't do hyperlinks
with the older Windows console.
2025-04-29 19:08:17 -04:00
David Korth
94c69214e7 [librpbase] TextOut_text.cpp: Colorize and underline external image hyperlinks.
NOTE: Underlining doesn't work on older Windows. (Definitely not WinXP or
Win7; possibly not Win10 prior to 1607.)
2025-04-29 18:49:14 -04:00
David Korth
bf61261b85 [rpcli] vt.cpp: Improve bold/bright tracking.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
FIXME: Set bold and/or bright if wAttributesOrig has FOREGROUND_INTENSITY?
2025-04-28 23:24:30 -04:00
David Korth
b4a81e5410 [rpcli] vt.cpp: Add bright foreground and background color attributes.
Bright foreground: 90-97
Bright background: 100-107

Note that these simply set the intensity flag and don't keep track of
whether or not "bright" was set, so setting a "regular" color won't
automatically remove the brightness.
2025-04-28 23:17:45 -04:00
David Korth
1a23dc8464 [rpcli] vt.cpp: Add "not underline" (24) to the ANSI escape sequence parser. 2025-04-28 23:13:56 -04:00
David Korth
365a7d5302 [rpcli] verifykeys.cpp: Colorize output.
Similar color scheme as rpcli.cpp:
- Status messages: Cyan
- Internal warnings: Yellow
- Valid keys: Green (for the "OK" message)
- Invalid keys: Red (for the error message)

The key names are not colorized.
2025-04-28 18:54:42 -04:00
David Korth
fb032f03ea NEWS.md: Mention the TERM check. 2025-04-28 18:49:26 -04:00
David Korth
16ad403a81 [rpcli] vt.cpp: Simplify init_posix_ConsoleInfo_t() a bit. 2025-04-28 18:45:40 -04:00
David Korth
397afc7166 [rpcli] vt.cpp: Check TERM once instead of twice.
TERM doesn't change for different file handles, so there's no need to
check it once for stdout and once for stderr.

Internal variable is_color_TERM is set by check_TERM_variable().
It's copied into ConsoleInfo_t for use elsewhere.
2025-04-28 18:44:08 -04:00
David Korth
a7c119805f [rpcli] Disable ANSI color on non-Windows systems if TERM isn't set to a valid color terminal.
Supported terminals match this regex:

(?i)^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux

rpcli.cpp: On Non-Windows systems, don't set OF_Text_UseAnsiColor if
the console doesn't support ANSI color.

vt.cpp: On Non-Windows systems, do nothing in the various Console*()
color functions if the console doesn't support ANSI color.
2025-04-28 18:40:12 -04:00
David Korth
191cbab172 [cmake] gcc.cmake: Add some more clang libc++ hardening options.
These options are now only applied if compiling with clang.

While it's possible to use libc++ with gcc, it requires a lot of manual
changes, and basicaly no one does it. (libstdc++ with clang is commonly
done on desktop Linux systems, though.)

Don't -D_LIBCPP_ENABLE_ASSERTIONS on clang-17 or later. It's deprecated,
and may result in a compile error. (...though on Android/Termux with
clang-20.1.3, it didn't...)
2025-04-28 18:22:21 -04:00
David Korth
bd5b649bf3 [libromdata] CMakeLists.txt: Bump the SOVERSION to 6.1.
It's ABI-compatible with 6.0 (using only .so.6, not .so.6.1), but there
have been changes since the previous release.
2025-04-28 18:21:02 -04:00
David Korth
3e853a59da [cmake] Don't enable -Werror or /WX by default; add a CMake option -DENABLE_WERROR.
Newer compilers usually add more warnings, so having -Werror by default
will most likely result in a compile error when new compiler versions
are released.

MSVC: Remove "-D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING". This is no
longer relevant, since we don't support anything older than MSVC 2015.
2025-04-28 18:19:53 -04:00
David Korth
1dc3609bc7 [rpcli] rpcli.cpp: Colorize output in ExtractImages().
NOTE: Using Yellow for cases where an animated icon is requested but
libpng doesn't support APNG.

Add "is" to the "APNG is not supported" line.
2025-04-28 18:19:02 -04:00
David Korth
b347c4fad6 [rpcli] vt.cpp: Handle len < 0 in the Win32 UTF-16 case.
Previously, when we used utf8_to_utf16(), this was automatically handled
by utf8_to_utf16(). Since we're not using that anymore, we have to call
strlen() ourselves. Otherwise, MultiByteToWideChar() will add the extra
NULL byte to the character count, resulting in an extra "space" being
written to the console. This causes the "-- Extracting..." text to be
offset by one space when extracting an internal image.

This fixes a regression from commit faeca807bd.
([rpcli] rpcli.cpp: Add color to the libgnuintl-8.dll and romdata-6.dll error messages.)
2025-04-28 18:16:52 -04:00
David Korth
7d379f826d [cmake] gcc.cmake: Fix DT_RELR enablement.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
It seems this was broken since it was initially implemented in v2.0
in commit d732fbc010
([cmake] platform/gcc.cmake: Initial support for detecting DT_RELR.)
because TMP_HAVE_DT_RELR was unset too early.
2025-04-28 01:03:31 -04:00
David Korth
3b8d47fa0b [rpcli] rpcli.cpp: Clear attributes before printing the newline.
This does mean we can't use ConsolePrint()'s newline parameter, so we'll
have to call ConsolePrintNewline() separately.

TextOut_text.cpp effectively does this already for "warning" fields.
2025-04-27 19:33:27 -04:00
David Korth
91d51920df [rpcli] vt.cpp: Use "\033[0m" instead of "\033[m".
Both are equivalent, but "0" might be more compatible.
2025-04-27 19:24:28 -04:00
David Korth
21e692e9cf NEWS.md: Mention rpcli colorizing more stuff. 2025-04-27 19:21:53 -04:00
David Korth
faeca807bd [rpcli] rpcli.cpp: Add color to the libgnuintl-8.dll and romdata-6.dll error messages.
NOTE: ConsolePrint() currently uses utf8_to_utf16() if printing to a
Windows console and ANSI isn't supported. This function is located
in libromdata (librptext), so we can't use it if romdata-6.dll is
missing. Use MultiByteToWideChar() directly instead. This might also
slightly improve performance, since an std::u16string is no longer
needed.

GDI+ init error: Localize the string. This can be localized because
libgnuintl-8.dll was already verified to be present at this point.
2025-04-27 19:18:20 -04:00
David Korth
7726fc6dfd [libi18n] i18n.h: Remove #include <tchar.h> and don't use _T() for LIBGNUINTL_DLL.
[rpcli] rpcli.cpp: Use _T(LIBGNUINTL_DLL) here.

[win32] NetworkStatus.c, ConfigDialog.cpp: #include <tchar.h>
2025-04-27 19:08:50 -04:00
David Korth
de6252e2d4 [rpcli] rpcli.cpp: Use colors for some status messages.
ROM filename and ATA/SCSI inquiry messages are now printed in cyan.
Error messages in those functions are now printed in red.

vt.cpp: Add two new functions:
- ConsoleSetTextColor(): Set the text color (ANSI value 0-7).
  Has an optional 'bold' argument.
- ConsoleResetTextColor(): Reset the text color.

On Windows, if not using ANSI escape sequences, this uses Windows
console attributes.

TODO: Add an option to force-enable/force-disable color.
2025-04-27 18:48:54 -04:00
David Korth
abee829b01 [libromdata/tests] RomHeaderTest: Update MegaDrive for the Teradrive TMSS external image.
TODO: Maybe split the MegaDrive tests into multiple files?
2025-04-27 18:48:19 -04:00
David Korth
dc2649beff [libromdata] MegaDrive: Add external image URL support for the Teradrive TMSS ROM.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
2025-04-27 15:31:30 -04:00
David Korth
2be8490e97 [libromdata] CBMDOS: Move "Directory" to the "RomData" context.
It's also used by the SNES class for Nintendo Power cartridges.
2025-04-26 15:56:00 -04:00
David Korth
8d7f709f8b [libromdata] ISOPrivate::host32(): Fix a typo that broke "Volume Size" on CD-i volumes.
Some checks are pending
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Waiting to run
Need to use be32_to_cpu() for 32-bit values, not be16_to_cpu().

This fixes a regression from commit 5cfce44312.
([libromdata] ISO: Always use host-endian except for CD-i, in which case, always use big-endian.)

Affects: v1.8 - v2.5

NOTE: v1.8 was the first version with CD-i support, so this was
effectively "always" broken.
2025-04-26 15:12:55 -04:00
David Korth
62ef8c18f4 [kde] RomDataView: Adjust the QTreeView sorting even if the header isn't visible.
Sorting still applies even if we can't see the header, e,g, for
Nintendo3DS permissions.
2025-04-26 13:35:28 -04:00
David Korth
eefaf5040d [libromdata] SNESPrivate::isSnesRomHeaderValid(): Check new_publisher_code.u16 != 0 instead of checking each character individually.
The Nintendo Power changes added a char/uint16_t union for
new_publisher_code, so take advantage of it here.
2025-04-26 13:32:32 -04:00
David Korth
81555db6b5 NEWS.md: Mention that we fixed #154: SNES: Nintendo Power directory 2025-04-26 13:13:33 -04:00
David Korth
64d66c038f [libromdata/tests] RomHeaderTest: Add tests for the two Nintendo Power full cartridge dumps I have available.
NOTE: The test suites are run with LC_ALL="C.UTF-8". This disables
localization for strings and numeric formatting, but it does *not*
disable wcwidth() handling for Japanese text.

On Windows, we're using gnulib's wcwidth() aka uc_width(), so the
locale doesn't affect Japanese text handling there, either.
2025-04-26 13:09:22 -04:00
David Korth
edd89a0b1c [libromdata] SNES: List the Nintendo Power directory for full NP cartridge dumps.
Currently shows the directory index, title (in Japanese), game code,
timestamp (directly as it's listed, no timezone adjustments), and
kiosk ID.
2025-04-26 12:35:40 -04:00
David Korth
02d7fbfdfa [kde] RomDataView: QTreeView is defaulting to sorting by column 0, descending.
Make it sort in ascending order by default instead.

NOTE: Using column -1 to suppress the sort indicator visibility.

Might want to guard this with QT_VERSION_CHECK(6, 0, 0), but it seems
to have no effect on KF5 on my system, but it might on some other
systems with weird shenanigans happening...
2025-04-26 12:33:44 -04:00
David Korth
48a98edc13 NEWS.md: The next release will be v2.5.1.
No major new features, just some bug fixes.
2025-04-26 11:29:50 -04:00
David Korth
755a28f910 NEWS.md: Mention the ISO sector mode changes.
Fixes #322: Underlying CD image type for ISO
Reported by @DankRank.
2025-04-26 11:26:54 -04:00
David Korth
e5cc30dc03 [libromdata] ISO::loadFieldData(): CD-i has its own sector format.
NOTE: Not putting this in CdromSectorInfo or SparseDiscReader because
the CD-i sector format is exclusively used for CD-i titles.
2025-04-26 11:25:20 -04:00
David Korth
c175d25696 [libromdata] ISO: Show the sector format instead of just the sector size.
Format is displayed as e.g. "MODE1/2048". If subchannels are present,
they are added as e.g. "+96".

TODO: More testing.
2025-04-26 11:16:46 -04:00
David Korth
d379fda1d3 [libromdata] ISO: Use a CdromSectorInfo instead of an individual sector_size variable.
The constructor will initialize the mode and subchannel size as necessary.

NOTE: This likely won't be used much due to the SparseDiscReader
changes in v2.3.
2025-04-26 11:12:49 -04:00
David Korth
2e09b9ae3f Rework the CD-ROM specific info to be stored in a struct.
New CdromSectorInfo struct in cdrom_structs.h.

Move cdrom_structs.h to librpbase so it can be used by SparseDiscReader.

SparseDiscReader now has a single function, cdromSectorInfo(), that
either retrieves a pointer to the CdromSectorInfo or nullptr if it
isn't set.
2025-04-26 11:04:31 -04:00
David Korth
5a738f8277 [libromdata] ISO: Get the sector size from the underlying disc reader classes if not reading directly from a file.
The SparseDiscReader changes in v2.3 broke this, so anything that uses
an ISO-9660 format showed 2048-byte sectors, even if this wasn't the case.

SparseDiscReader subclasses now have a set of CD-ROM specific fields to
set, e.g. CD-ROM sector size, mode, and subchannels. For multi-track
images, this should be set for the "main" data track.

Updated the following classes to set these fields:
- CdiReader (uses Track 02 for Dreamcast games)
- GdiReader (uses Track 03 for Dreamcast games)
- Cdrom2352Reader (always uses 2352-byte sectors, but gets mode from
  the first sector)
- CisoPspReader (always uses MODE1/2048)

GameCube and Wii disc reading classes don't set these, since they aren't
CD-ROM formats with multiple sector sizes.
2025-04-26 10:48:52 -04:00
David Korth
8e78811e8a NEWS.md: The EXE manifest bug only affects v2.5. 2025-04-26 09:55:14 -04:00
David Korth
cb3ada3e88 [gettext.win32] Recompiled with gcc-15.1.0.
Some checks failed
Codecov / run (push) Waiting to run
CodeQL / Analyze (cpp) (push) Has been cancelled
2025-04-25 18:23:11 -04:00
David Korth
83b5dddfd5 Merge branch 'feature/win32-rpcli-WriteConsole' 2025-04-25 18:22:29 -04:00
David Korth
2934ccd46a [rpcli] vt.cpp, win32_console_print_ansi_color(): Convert the if/else block to switch/case.
Some checks failed
Codecov / run (push) Has been cancelled
gcc is able to optimize the if/else block into a jump table, but MSVC
gets confused and fails to optimize it. Converting to switch/case
allows both compilers to optimize it using a jump table.

The gcc version might be slightly bigger now due to explicitly stating
the 30-37 and 40-47 cases instead of checking ranges, but it might be
slightly faster due to not having to check ranges and instead simply
jumping to the correct case.
2025-04-24 01:53:04 -04:00
David Korth
4a1287da34 [rpcli] vt.cpp: Handle a few more attributes.
- 22: normal intensity
- 39: default foreground color
- 49: default background color
2025-04-24 01:51:14 -04:00
David Korth
141048d453 [rpcli] vt.cpp: Fix a typo that broke background color handling.
Should be checking for [40,47], not [40,37].
2025-04-24 01:51:14 -04:00
David Korth
f044ef5559 [rpcli] vt.cpp: Handle the Reset sequence and some more attributes.
\033[m with no number should be interpreted as 0 (Reset).

Also, simply ignore invalid (unsupported) attribute numbers instead
of stopping \033[m processing entirely. Otherwise, the 'm' might
end up getting printed.

Add support for the following attributes:
- 4 (underline)
- 7 (reverse video)
- 27 (not-reverse video)

NOTE: These work on Windows 10, but not Windows 7. The Windows 10 support
is redundant, since on Windows 10, we're normally sending ANSI escape
sequences directly to the console, instead of using the custom handler.

Maybe these attributes work on Windows 8 and/or 8.1?
2025-04-24 01:50:45 -04:00
David Korth
91d7fa8584 [rpcli] vt.cpp, ConsolePrintNewline(): Fix copy/paste error in the stdio fallback path. 2025-04-24 01:21:16 -04:00
David Korth
740da2d882 [rpcli] vt.hpp: Reduce ConsoleInfo_t size on Windows.
Move `uint16_t wAttributesOrig` before `HANDLE hConsole`. HANDLE is
64-bit aligned (on 64-bit), so it ends up leaving some space after
the bools that we can reuse for the uint16_t.

64-bit Windows:
Size before: 32 bytes
Size after:  24 bytes
Difference:  -8 bytes

32-bit Windows:
Size before: 16 bytes
Size after:  16 bytes
Difference:   0 bytes

Effectively no difference on 32-bit, but reduces it by 8 bytes on 64-bit.
2025-04-24 01:13:05 -04:00
David Korth
ca67d8c20d [rpcli] vt.cpp: On Windows 10, MinTTY (git bash, cygwin) acts like a real console.
WriteConsole() works, etc.

TODO: Verify Windows 7 behavior.
2025-04-24 01:10:35 -04:00
David Korth
aa6cbba46e [rpcli] vt.cpp: Constify ConsoleInfo_t* parameters. 2025-04-24 01:09:32 -04:00
David Korth
7990dd3364 [rpcli] vt.cpp: New function ConsolePrintNewline().
This prints a newline using WriteConsole() on Windows if possible.
Otherwise, it uses stdio.

Use ConsolePrintNewline() anywhere putchar('\n') or fputc('\n', stdxxx)
was used.

TODO: Optimize by not requiring a full utf8_to_utf16() here?
That might be a "super-micro-optimization", though...
2025-04-24 01:08:21 -04:00
David Korth
deb63624bc [rpcli] vt.cpp: Add an explicitly-counted version of ConsolePrint().
This eliminates an strlen() when using a C++ string.

There are now two inline wrappers:
- one for C strings with implicit length
- one for C++ strings with explicit length

Both of these wrappers call the real ConsolePrint, which takes an
explicit length and doesn't take any optional arguments.

Also, the C++ wrapper was returning the return value from a void
function, which somehow "worked", but isn't correct.

Use fwrite() instead of fputs() when the size is known.
2025-04-24 01:03:19 -04:00
David Korth
9a799984a9 [rpcli] rpcli.cpp: LibRpText::utf8_to_utf16() isn't used here.
I used it while doing some testing with WriteConsole(), but that
function is now called in vt.cpp, and not by rpcli.cpp directly.

Also removed `using std::u16string;`.
2025-04-23 00:10:11 -04:00
David Korth
0728d16649 [rpcli] rpcli.cpp: Check for libgnuintl-8.dll before romdata-6.dll.
romdata-6.dll also depends on libgnuintl-8.dll, so if libgnuintl-8.dll
is missing, romdata-6.dll won't be usable, either.

FIXME: libromdata doesn't appear to have a libgnuintl-8.dll check...
2025-04-23 00:05:35 -04:00
David Korth
73bc840583 [rpcli] vt.cpp, win32_write_to_console(): Use WriteConsoleA() if ANSI escape sequences are supported.
Support for ANSI escape sequences was added in Windows 10 1607, which
also handles UTF-8 console output correctly. Use WriteConsoleA() so
we don't have to convert from UTF-8 to UTF-16.
2025-04-22 22:12:35 -04:00
David Korth
953d80e483 [rpcli] rpcli.cpp, DoFile(): Use the non-ANSI version even on Windows 10 1607 and later.
WriteConsole() is faster than printf/cout on Windows.

TODO: Maybe use WriteConsoleA() instead, so we can take advantage of
ANSI escape and UTF-8 support while also getting the performance benefit
of WriteConsole().
2025-04-22 21:54:53 -04:00
David Korth
4a238c2f1e [rpcli] TODO: If using Win10 1607 with UTF-8, use WriteConsoleA()? 2025-04-22 21:39:38 -04:00
David Korth
166e773f3f [rpcli] verifykeys.cpp: Use ConsolePrint(). 2025-04-22 21:15:19 -04:00
David Korth
7273c8b658 [rpcli] rpcli.cpp, ShowUsage(): Forgot to remove a fputc('\n', stderr);.
This resulted in an extra newline when showing usage in builds that
support decryption.

This fixes a regression from commit aa6f1aba07.
([rpcli] rpcli.cpp: New function ConsolePrint(), now used by ShowUsage().)
2025-04-22 21:11:37 -04:00
David Korth
539bdcd2b3 [rpcli] vt.cpp, init_vt(): Initialize the ConsoleInfo_t streams on Linux, too.
Somehow missed this in commit a2a61e614163f1c5968421803130bb2d88b369b0...
([rpcli] Rework the various Windows console functions to take ConsoleInfo_t*.)
2025-04-22 21:10:04 -04:00
David Korth
6cb4cbb503 [rpcli] Move ConsolePrint() from rpcli.cpp to vt.cpp.
ConsolePrint() works on both Windows and Linux.

On Linux, it merely calls stdio functions.

On Windows, it calls stdio functions if not using a real console.
Otherwise, it uses WriteConsole().
2025-04-22 21:03:49 -04:00
David Korth
5cb7db18ea [rpcli] rpcli.cpp: Minor syntax error. (oops!) 2025-04-22 21:03:16 -04:00
David Korth
2cd5fc45f4 NEWS.md: Mention UTF-8 improvements in rpcli. 2025-04-22 21:00:41 -04:00
David Korth
3f285b2762 [rpcli] rpcli.cpp, _tmain(): Use ConsolePrint(). 2025-04-22 20:57:46 -04:00
David Korth
b1227d7699 [rpcli] rpcli.cpp, DoScsiInquiry() and DoAtaIdentifyDevice(): Use ConsolePrint() more. 2025-04-22 20:49:53 -04:00
David Korth
6a62448232 [rpcli] rpcli.cpp, DoAtaIdentifyDevice(): Missing packet parameter in the WriteConsole() path. 2025-04-22 20:48:47 -04:00
David Korth
ec7df32cda [rpcli] rpcli.cpp, PrintSystemRegion() and PrintPathnames(): Use ConsolePrint(). 2025-04-22 20:35:23 -04:00
David Korth
f8d6e76510 [rpcli] rpcli.cpp, ExtractImages() and DoFile(): Use ConsolePrint().
Add a ConsolePrint() overload that takes std::string.

NOTE: May be more efficient if the std::string overload calls
win32_write_to_console() with an actual length parameter, but
it takes more effort to maintain two versions of this function...
2025-04-22 20:31:16 -04:00
David Korth
d29169b35c [locale] es.po: Missing apostrophe in a string:
msgid "Extracting {0:s} into '{1:s}'"
msgstr "Extracción de {0:s} en '{1:s}'"
2025-04-22 20:26:40 -04:00
David Korth
a2a61e6141 [rpcli] Rework the various Windows console functions to take ConsoleInfo_t*.
Add FILE* and HANDLE (on Windows only) to ConsoleInfo_t.

vt.cpp: GetStdHandle() returns INVALID_HANDLE_VALUE on error,
so check for that.
2025-04-22 20:17:58 -04:00
David Korth
aa6f1aba07 [rpcli] rpcli.cpp: New function ConsolePrint(), now used by ShowUsage().
On Windows, ConsolePrint() uses win32_write_to_console() to print
Unicode text using WriteConsoleW() if a real console is in use.
2025-04-22 20:05:34 -04:00
David Korth
03d3400e27 [rpcli] rpcli.cpp: Use WriteConsole() for ATA and SCSI inquiries. 2025-04-22 19:52:31 -04:00
David Korth
8e48fd28f1 [rpcli] DoScsiInquiry(): Fix an inverted condition that broke SCSI inquiry.
It was showing an error if the file specified was in fact a device file,
which prevents it from working.

This fixes a regression from commit 837315505e.
([rpcli] rpcli.cpp: Un-indent a few functions.)

Affects: v2.3 - v2.5
2025-04-22 19:51:44 -04:00
David Korth
3bbe0f63c5 [rpcli] vt.cpp: Create a struct for the console properties and split it into stdout/stderr.
This will be useful when updating the stderr stuff in rpcli.cpp to use
WriteConsole() for both Unicode and performance reasons.

rpcli.cpp: Update for this change.
2025-04-22 19:37:32 -04:00
David Korth
bb5213ab60 [rpcli] vt.cpp: New variable is_real_console.
This is true if using a real Windows console, and false if using e.g.
MinTTY. MinTTY supports ANSI escape sequences, but not WriteConsole().

rpcli.cpp: Don't use WriteConsole() if we aren't using a real console.
2025-04-22 19:20:58 -04:00
David Korth
5a6309417c [rpcli] rpcli.cpp, DoFile(): Always use WriteConsole() for JSON.
This is faster than even using UTF-8 output on Windows 10 1607.

vt.cpp: win32_write_to_console(): Write in 4096-character chunks.
WriteConsole() seems to fail if the input buffer is > 64 KiB.

rpcli's JSON for rpcli.exe is 40,057 characters, which is > 64 KiB
with UTF-16 and failed to write. (The ANSI version "worked", though
without Unicode handling.)
2025-04-22 19:15:54 -04:00
David Korth
5833175378 [rpcli] Use WriteConsole() for text and JSON output.
WriteConsole() with Unicode (UTF-16) text seems to work around the
issue that was causing UTF-8 output to freeze on Windows 7. It's also
quite a bit faster than printf/cout on Windows.

WriteConsole() *does* work with ANSI escape sequences on Windows 10 1607,
so I'm going to do some reworking to make more use of it.

CMakeLists.txt: Remove the std::string_view check, since it's no longer
used in vt.cpp.
2025-04-22 18:58:21 -04:00
David Korth
8f23cc85d9 NEWS.md: Mention the Windows UTF-8 console output issues, and add a v2.5 entry for this. 2025-04-21 23:38:59 -04:00
David Korth
18d005bb2b FIXME: On Windows 7, UTF-8 console output can randomly crash the program.
Some checks failed
Codecov / run (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
Not sure why. It's probably a limitation of the older console.

It works on Windows 10. (tested on 1809)

TODO: Does it work on Windows 8 or 8.1?
2025-04-21 23:36:12 -04:00
David Korth
602165f822 [libi18n] gettext.h: Synchronize with the latest version from gnulib.
Updated in gnulib on 2025/01/01.
2025-04-21 23:27:55 -04:00
David Korth
684ef662a7 [gettext.win32] Updated to gettext-0.24.
Compiled with:
- i386:  gcc-14.2.1_p20241116, MinGW-w64 12.0.0
- amd64: gcc-14.2.1_p20241221, MinGW-w64 12.0.0

I tried updating it before, but every time I rebuilt gettext, it would
cause all of rom-properties to crash on startup. It turns out the
problem was -Wl,--pic-executable; removing this fixed it.

This *might* prevent ASLR .reloc sections from being generated in the
gettext executables. These are only used at compile time, so it's not
that big of an issue.

Removed most of the patches, since they are no longer necessary.
The remaining patches:

- 001-gettext-runtime-disable-iconv.patch
- 122-Use-LF-as-newline-in-envsubst.patch

Both patches have been updated for gettext-0.24.

TODO: Build for arm, arm64, and arm64ec.
2025-04-21 20:37:26 -04:00
David Korth
384c3d5abb [tracker] tracker-mini.c: Simplify the API version check a bit.
Check that the first .so file was opened before opening the second one.

Code size difference: (64-bit Gentoo Linux, gcc-14.2.1_p20250301, release build, no LTO)

   text    data     bss     dec     hex filename
   1798      96     160    2054     806 tracker-mini.c.o [before]
   1774      96     160    2030     7ee tracker-mini.c.o [after]
    -24       0       0     -24     -18 Difference
2025-04-21 20:31:40 -04:00
David Korth
9493b2c374 [tracker] tracker-mini.c: Use a loop to check for the various API versions.
Code size difference: (64-bit Gentoo Linux, gcc-14.2.1_p20250301, release build, no LTO)

   text    data     bss     dec     hex filename
   2198       0     160    2358     936 tracker-mini.c.o [before]
   1798      96     160    2054     806 tracker-mini.c.o [after]
   -400     +96       0    -304    -130 Difference
2025-04-21 20:29:38 -04:00
David Korth
a3f4a3861d [libromdata] EXEPrivate::addFields_PE(): Don't show the "XML parsing failed" warning if the EXE doesn't actually have a manifest. 2025-04-21 20:25:40 -04:00
David Korth
e1c90493e2 [tracker] tracker-mini.c: Forgot to call close_modules() after checking for LocalSearch 3.8. 2025-04-20 16:52:38 -04:00
David Korth
ee887913a6 [debian] rules: Set TRACKER_INSTALL_API_VERSION=AUTO.
Otherwise, I might forget to update it when building for various versions
of Ubuntu, which will result in Tracker being installed in the wrong
place for most newer versions.
2025-04-20 16:50:54 -04:00
David Korth
36da8b7168 NEWS.md: Mention localsearch support. 2025-04-20 16:32:50 -04:00
David Korth
3780a5b2e7 [tracker] Add support for localsearch-3.8, aka tracker-3.8.
Various pathnames were changed, but the API is essentially the same.

The API version will be handled as "3L".

dlopen-notes.h: Add ELF_NOTE_DLOPEN8().

[tracker] dlopen-notes.c: Add the API 3L library names.

NOTE: The Ubuntu 25.04 packages were all compiled with a hard-coded
-DTRACKER_INSTALL_API_VERSION=1. This should probably be removed from
debian/rules and we should just rely on auto-detection.

TODO: Release a v2.5.1 with this fix?
2025-04-20 16:30:04 -04:00
David Korth
d60312e3eb [tracker] 14-rp-rom-images.rule: Add "nfo:GameImage" as a fallback type.
tracker-3.8 (localsearch-3.8) has this in 15-games.rule.
2025-04-20 16:21:01 -04:00
David Korth
7513c2f45d [tracker] 14-rp-textures.rule: Add image/qoi and image/x-qoi.
Forgot to do this when adding support for Qoi images in v2.5.
2025-04-20 14:43:56 -04:00
David Korth
c5331ad0e4 [libromdata/tests] RomHeaderTest: Add KQ9E01 (Zelda 4SWORD) to the NintendoDS test.
This DSiWare SRL has an animated icon.
2025-04-20 14:17:27 -04:00
David Korth
cdfdf04d7e [libromdata] NintendoDS_BNR: Assume the icon isn't animated if frame 0 delay is 1 but frame 1 delay is 0.
Delay of 0 means "end of sequence". This effectively is the same as a
static icon, but the previous method of just checking frame 0's delay
didn't work.

This resulted in the following ROM headers as being detected as having
an animated icon when they didn't:
- DMFEA4
- DSYESZ
- VSOE8P

TODO: Add one that does.

nds_structs.h: Mark some enum constants as unsigned.

This fixes a regression from commit f5d34d97cb.
([libromdata] NintendoDS_BNR::imgpf(): Check for animated icons.)
2025-04-20 14:09:36 -04:00
David Korth
18e2cdffa4 s/RestoreConsoleCP/RestoreConsoleOutputCP/ 2025-04-20 13:14:45 -04:00
David Korth
28b649388d [librptext/tests] TextFuncsTest: Work around the aggressive-loop-optimizations warning.
When compiling with LTO enabled on gcc-14.2.0 (e.g. with Ubuntu 25.04),
the following warning (as error) appeared. Work around it by checking for
str.empty() before resizing the string.

[cmake] gcc.cmake: Remove -Wno-error=aggressive-loop-optimizations, since
it's no longe needed.

In function ‘assign’,
    inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:455:23,
    inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:450:7,
    inlined from ‘_M_replace_aux’ at /usr/include/c++/14/bits/basic_string.tcc:471:17,
    inlined from ‘append’ at /usr/include/c++/14/bits/basic_string.h:1499:30,
    inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.tcc:405:14,
    inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.h:1119:21,
    inlined from ‘TestBody’ at src/librptext/tests/TextFuncsTest.cpp:513:12:
/usr/include/c++/14/bits/char_traits.h:837:25: error: iteration 9223372036854775807 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
  837 |           assign(__s[__i], __a);
      |                         ^
/usr/include/c++/14/bits/char_traits.h:836:34: note: within this loop
  836 |         for (size_t __i = 0; __i < __n; ++__i)
      |                                  ^
In function ‘assign’,
    inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:455:23,
    inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:450:7,
    inlined from ‘_M_replace_aux’ at /usr/include/c++/14/bits/basic_string.tcc:471:17,
    inlined from ‘append’ at /usr/include/c++/14/bits/basic_string.h:1499:30,
    inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.tcc:405:14,
    inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.h:1119:21,
    inlined from ‘TestBody’ at src/librptext/tests/TextFuncsTest.cpp:542:12:
/usr/include/c++/14/bits/char_traits.h:837:25: error: iteration 9223372036854775807 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
  837 |           assign(__s[__i], __a);
      |                         ^
/usr/include/c++/14/bits/char_traits.h:836:34: note: within this loop
  836 |         for (size_t __i = 0; __i < __n; ++__i)
      |                                  ^
lto1: all warnings being treated as errors
lto-wrapper: fatal error: /usr/bin/c++ returned 1 exit status
compilation terminated.
2025-04-20 11:34:43 -04:00
David Korth
3022868577 [pugixml] Disable functionality we don't need.
This reduces the size of pugixml.dll to within range of what
tinyxml-10.dll was in previous versions.

Size comparisons: (amd64 release build, with LTO, MSVC 2022 17.6.5)

tinyxml-10.dll in rom-properties 2.4.1: 105,472

pugixml.dll:
- With all enabled:     222,208
- Disable XPATH:        142,336
- + disable STL:        121,856
- + disable exceptions: 121,856

NOTE: Disabling exceptions doesn't seem to change the code size at all,
even if STL is left enabled.
2025-04-20 11:13:35 -04:00
David Korth
328c0047c8 [kde] Work around an issue where plugins try including fmt/format.h without linking to fmt.
Add a macro RP_NO_INCLUDE_LIBFMT_IN_STDAFX_H. This macro is defined by
the various KDE plugin projects that don't need libfmt.

All stdafx.h files that include fmt headers will now disable those
inclusions if RP_NO_INCLUDE_LIBFMT_IN_STDAFX_H is defined.

Removing stdafx.h from the KDE plugins wasn't a viable option because
e.g. ProxyForUrl.cpp includes it, and is part of the main KDE plugin
as well as the sub-plugins.

This should fix the following error when building on a system that
doesn't have a system-wide libfmt and is building the KDE UI frontend(s):

In file included from src/kde/kf5/../stdafx.h:35,
                 from src/kde/plugins/RomThumbCreator_p.cpp:9:
src/kde/kf5/../../rp-libfmt.h:14:10: fatal error: fmt/format.h: No such file or directory
   14 | #include <fmt/format.h>
      |          ^~~~~~~~~~~~~~
compilation terminated.
2025-04-20 11:00:07 -04:00
David Korth
108c853840 [cmake] gcc.cmake: -Wno-error=aggressive-loop-optimizations
This showed up on Ubuntu 25.04 with gcc-14.2.0. It didn't show up on my
laptop with gcc-14.2.1_p20250301...

(cherry picked from commit a904f3c408)
2025-04-20 05:37:44 -04:00
David Korth
d6fc415460 [cmake] gcc.cmake: Move -Wno-error=stringop-overread here.
The same error showed up on armhf and amd64 this time.

Since it's happening in LTO and not the main compiler step, the pragmas
likely aren't working properly. Use -Wno-error=stringop-overread instead.

(cherry picked from commit ec441b4cec)
2025-04-20 05:37:30 -04:00
David Korth
7e9dbb514d [libromdata] iQuePlayer: FIXME: False-positive error on Ubuntu 22.04 arm64 due to the use of unz_size/2.
In function ‘fromLinear16’,
    inlined from ‘loadImage’ at ./src/libromdata/Console/iQuePlayer.cpp:314:32:
./src/libromdata/../librptexture/decoder/ImageDecoder_Linear.hpp:135:77: error: ‘fromLinear16_cpp’ reading 12544 bytes from a region of size 8832 [-Werror=stringop-overread]
./src/libromdata/../librptexture/decoder/ImageDecoder_Linear.hpp: In member function ‘loadImage’:
./src/libromdata/../aligned_malloc.h:68:22: note: source object of size [6272, 8832] allocated by ‘aligned_alloc’
../librptexture/./src/librptexture/decoder/ImageDecoder_Linear.cpp:717:14: note: in a call to function ‘fromLinear16_cpp’ declared with attribute ‘access (read_only, 4, 5)’
lto1: all warnings being treated as errors
make[4]: *** [/tmp/ccktAlyL.mk:14: /tmp/cc86M3xK.ltrans4.ltrans.o] Error 1
make[4]: *** Waiting for unfinished jobs....
lto-wrapper: fatal error: make returned 2 exit status

TODO: Figure out how to fix this without simply suppressing the warning.

Also, this only happens on arm64. armhf and amd64 don't have this.

(cherry picked from commit 6796c43571)
2025-04-20 04:13:33 -04:00
David Korth
daa42d5201 [cmake] CPUInstructionSetFlags.cmake: Disable NEON on armhf for now. (except MSVC)
Adding "-marm -mfpu=neon" fixed compilation, but LTO linking failed:

/usr/lib/gcc/arm-linux-gnueabihf/9/include/arm_neon.h: In function ‘rp_byte_swap_32_array_neon’:
/usr/lib/gcc/armmake[3]: Entering directory '/<<PKGBUILDDIR>>/build'
-linux-gnueabihf/9/include/arm_neon.h:11401:14: fatal error: You must enable NEON instructions (e.g. ‘-mfloat-abi=softfp’ ‘-mfpu=neon’) to use these intrinsics.
11401 |   __rv.__o = __builtin_neon_vld2v4si ((const __builtin_neon_si *) __a);
      |              ^
compilation terminated.
lto-wrapper: fatal error: /usr/bin/c++ returned 1 exit status

I'll need to test this in qemu or similar first before trying it on
Launchpad again. For now, don't enable NEON on armhf.

...except when compiling with MSVC for Windows, since Windows on ARM
mandates NEON on both 32-bit and 64-bit.

(cherry picked from commit 5973d5af91)
2025-04-20 04:13:18 -04:00
David Korth
bdaa74058a [cmake] CheckPugiXML.cmake: PugiXML 1.10 doesn't define the alias target "pugixml::pugixml".
From Ubuntu Launchpad:

CMake Error at src/libromdata/CMakeLists.txt:488 (ADD_LIBRARY):
  Target "romdata" links to target "pugixml::pugixml" but the target was not
  found.  Perhaps a find_package() call is missing for an IMPORTED target, or
  an ALIAS target is missing?

(cherry picked from commit 5481b385f5)
2025-04-20 04:11:50 -04:00
David Korth
ac5838e4fc [cmake] CPUInstructionSetFlags.cmake: "ANDNOT" -> "AND NOT"
(cherry picked from commit 075ae289bb)
2025-04-20 04:11:23 -04:00
David Korth
6f510ffb57 [cmake] CPUInstructionSetFlags.cmake: Set NEON_FLAGS to "-marm -mfpu=neon" on 32-bit ARM.
[librpbyteswap,librptexture] Apply NEON_FLAGS on 32-bit ARM.

The Ubuntu 18.04 armhf build failed to compile:

/<<PKGBUILDDIR>>/src/librpbyteswap/byteswap_neon.c: In function ‘rp_byte_swap_16_array_neon’:
/usr/lib/gcc/arm-linux-gnueabihf/7/include/arm_neon.h:11880:1: error: inlining failed in call to always_inline ‘vst2q_u16’: target specific option mismatch
 vst2q_u16 (uint16_t * __a, uint16x8x2_t __b)
 ^~~~~~~~~
/<<PKGBUILDDIR>>/src/librpbyteswap/byteswap_neon.c:48:3: note: called from here
   vst2q_u16(ptr, vec);
   ^~~~~~~~~~~~~~~~~~~

It seems NEON is disabled by default on armhf.

NOTE: Not rebuilding for armhf on Ubuntu 18.04.
(cherry picked from commit 66c43ccb4a)
2025-04-20 04:11:20 -04:00
David Korth
fc9bcc275f [cmake] gcc.cmake: -Wno-error=cast-align
The Ubuntu 16.04 Launchpad build for armhf failed due to a potential
alignment issue:

/<<PKGBUILDDIR>>/src/kde/AchQtDBus.cpp: In member function ‘int AchQtDBus::notifyFunc(LibRpBase::Achievements::ID)’:
/<<PKGBUILDDIR>>/src/kde/AchQtDBus.cpp:149:59: error: cast from ‘uchar* {aka unsigned char*}’ to ‘LibRpTexture::argb32_t*’ increases required alignment of target type [-Werror=cast-align]
   argb32_t *bits = reinterpret_cast<argb32_t*>(icon.bits());
                                                           ^

This shouldn't be an actual problem, since rp_image's image data is
always 16-byte aligned.

NOTE: Not rebuilding the Ubuntu 16.04 packages for ARM because of this.
(Both the armhf and arm64 builds were cancelled.)

(cherry picked from commit 5a08131311)
2025-04-20 04:10:52 -04:00
David Korth
f5d34d97cb [libromdata] NintendoDS_BNR::imgpf(): Check for animated icons.
This was previously handled by NintendoDS before banner parsing was
split out into a separate RomData subclass.

Without IMGPF_ICON_ANIMATED, rpcli won't indicate if an animated icon
is present, but it can still be extracted with `-a`.

This fixes a regression from commit f2565965b2.
([libromdata] NintendoDS_BNR: Split icon/title data parsing out of NintendoDS.)

Affects: v2.4 - v2.5
2025-04-20 03:01:14 -04:00
David Korth
fc85e53318 Version bump for development. (v2.5+) 2025-04-20 02:58:54 -04:00
413 changed files with 15661 additions and 6778 deletions

View File

@ -1,5 +1,5 @@
# ROM Properties Page Shell Extension # ROM Properties Page Shell Extension
CMAKE_MINIMUM_REQUIRED(VERSION 3.5) CMAKE_MINIMUM_REQUIRED(VERSION 3.5...3.10)
# CMP0048: Set VERSION variables based on the project version specified in PROJECT(). # CMP0048: Set VERSION variables based on the project version specified in PROJECT().
# Introduced in CMake 3.0. # Introduced in CMake 3.0.
@ -27,6 +27,12 @@ IF(POLICY CMP0151)
CMAKE_POLICY(SET CMP0151 NEW) CMAKE_POLICY(SET CMP0151 NEW)
ENDIF(POLICY CMP0151) ENDIF(POLICY CMP0151)
# CMP0177: Normalize INSTALL() destination paths.
# Introduced in CMake 3.31.
IF(POLICY CMP0177)
CMAKE_POLICY(SET CMP0177 NEW)
ENDIF(POLICY CMP0177)
# Read the project version. # Read the project version.
CONFIGURE_FILE(version.txt version.txt.tmp) CONFIGURE_FILE(version.txt version.txt.tmp)
FILE(STRINGS version.txt RP_VERSION_FILE) FILE(STRINGS version.txt RP_VERSION_FILE)
@ -89,13 +95,13 @@ SET(CMAKE_C_STANDARD_REQUIRED OFF)
SET(CMAKE_C_EXTENSIONS ON) SET(CMAKE_C_EXTENSIONS ON)
SET(CMAKE_CXX_STANDARD_REQUIRED OFF) SET(CMAKE_CXX_STANDARD_REQUIRED OFF)
SET(CMAKE_CXX_EXTENSIONS ON) SET(CMAKE_CXX_EXTENSIONS ON)
IF(CMAKE_VERSION VERSION_GREATER 3.20) # >= 3.21 IF(CMAKE_VERSION VERSION_GREATER 3.20.99) # >= 3.21
SET(CMAKE_C_STANDARD 17) SET(CMAKE_C_STANDARD 17)
SET(CMAKE_CXX_STANDARD 20) SET(CMAKE_CXX_STANDARD 20)
ELSEIF(CMAKE_VERSION VERSION_GREATER 3.11) # >= 3.12 ELSEIF(CMAKE_VERSION VERSION_GREATER 3.11.99) # >= 3.12
SET(CMAKE_C_STANDARD 11) SET(CMAKE_C_STANDARD 11)
SET(CMAKE_CXX_STANDARD 20) SET(CMAKE_CXX_STANDARD 20)
ELSEIF(CMAKE_VERSION VERSION_GREATER 3.7) # >= 3.8 ELSEIF(CMAKE_VERSION VERSION_GREATER 3.7.99) # >= 3.8
SET(CMAKE_C_STANDARD 11) SET(CMAKE_C_STANDARD 11)
SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_CXX_STANDARD 17)
ELSE() ELSE()

99
NEWS.md
View File

@ -1,5 +1,103 @@
# Changes # Changes
## v2.6 (released 2025/??/??)
* New parsers:
* ICO: Windows icons and cursors. Supports most icons and cursors designed
for Windows 3.x and later (including Windows Vista PNG-format icons),
plus the old Windows 1.x format. Only the "best" version for each icon
is selected for thumbnailing. (Largest size and highest color depth.)
* Icon thumbnailing is not actually enabled on Windows and Linux systems
at the moment, since it may conflict with system icon handling.
It's mostly only usable for rpcli and for use as a subclass elsewhere.
* Partially fixes #170: Icon files: ICNS, ICO, EXE
* New parser features:
* Xbox360_STFS: Fix titles for some packages that were authored incorrectly
and have mojibake titles. Specifically, the titles were originally encoded
as UTF-8, but when building the package, they were handled as if they were
cp1252 when being converted to UTF-16BE.
* Fixes #450: X360 - Non-Latin Titles appearing as mojibake
* Reported by @Masamune3210.
* EXE: The application icon can now be extracted using rpcli.
* ISO: AUTORUN.INF is now parsed. This includes a tab showing the contents
of AUTORUN.INF, as well as the disc icon from a .ico or .exe/.dll file.
* Fixes #232: ISO: Parse autorun.inf
* ISO: Joliet file systems are now partially supported. This was added to
handle older Windows disc images that use a long filename for the icon,
and the disc is authored with Joliet for long filenames but an old version
of ISO-9660, resulting in 8.3 filenames in the ISO-9660 directories.
* Bug fixes:
* Windows: Work around a potential libpng crash when attempting to read
empty data as a PNG image. (Needs more debugging for a proper fix...)
* See #451: libpng errors crash due to libpng setjmp/longjmp (Windows 10, release builds only)
* Reported by @Masamune3210.
* Qoi: R/B channels were incorrectly swapped when this was first added in v2.5.
* Affects: v2.5 - v2.5.1
* Fix an issue where an 'abgr' swizzle might fail on little-endian systems.
* Other changes:
* rpcli: Added more colorization for warning messages.
* rpcli: Refactored console handling into a separate library, libgsvt.
* IsoPartition: Implemented readdir(). Not currently used by anything, though.
* KDE (KF5, KF6): Improved image quality for RFT_LISTDATA fields with icons.
## v2.5.1 (released 2025/05/10)
* New parser features:
* ISO: Show the sector mode in addition to sector sizes.
* Fixes #322: Underlying CD image type for ISO
* Requested by @DankRank.
* SNES: List the Nintendo Power directory for full NP cartridge dumps.
* Fixes #154: SNES: Nintendo Power directory
* MegaDrive: Add external image URL support for the Teradrive TMSS ROM.
* Bug fixes:
* NintendoDS_BNR: Animated icons were missing the animated icon flag.
* Affects: v2.4 - v2.5
* EXE: Don't show the "XML parsing failed" warning if the EXE doesn't
actually have a manifest.
* Affects: v2.5
* rpcli: SCSI inquiry was accidentally broken during a code cleanup.
* Affects: v2.3 - v2.5
* ISO: Get the sector size from the underlying disc reader classes if
not reading directly from a file.
* The SparseDiscReader changes in v2.3 broke this, so anything that
uses an ISO-9660 format showed 2048-byte sectors, even if this
wasn't the case.
* KDE: On KF6, ListData widgets that didn't specify a default sorting
method ended up being sorted in reverse-order by default. Not sure
why this changed in Qt6. A workaround has been applied to fix it.
* ISO: Fix a typo that broke "Volume Size" on CD-i volumes.
* Affects: v1.8 - v2.5
* Build system: DT_RELR detection was broken and didn't work properly
since it was implemented in v2.0. It now works properly.
* GTK4: Fix a potential crash in DragImage when using `rp-stub -R`.
* WiiUPackage: vWii packages are now handled properly.
* Other changes:
* Added support for localsearch-3.8, the new name of Tracker.
This is internally handled as API "3L".
* Fixes #446: Use `localsearch` paths instead of `tracker3-miners`
* Reported by @lufog.
* rpcli: Improved Unicode output such that it works properly on older versions
of Windows, including Windows XP and Windows 7, by using WriteConsoleW().
This requires converting from UTF-8 to UTF-16, but it turns out doing this
is actually faster than printf/cout, even on versions of Windows that support
UTF-8 properly, so now it's used on Windows 10 as well.
* rpcli: Some more status and error messages are now colorized if printing to
a console. (Cyan for status messages; red for error messages.)
* Colorization is now disabled on non-Windows systems if TERM is not set to
a terminal that supports color.
* URLs are now colorized and marked up using "OSC 8", which makes them
clickable on terminals that support it.
* The xattr tab now supports displaying file compression algorithms in some
cases. On Windows, it will indicate LZNT1 ("standard" NTFS compression) on
all versions, and if using Windows 10 or later, it will indicate newer
algorithms in use, e.g. the XPRESS and LZX algorithms. On Linux, btrfs's
zlib, lzo, and zstd algorithms will be displayed.
## v2.5 (released 2025/04/19) ## v2.5 (released 2025/04/19)
* New parsers: * New parsers:
@ -86,6 +184,7 @@
can get tripped up because it uses C-style varargs. can get tripped up because it uses C-style varargs.
* rpcli: Text output for "warning" messages is now colorized if * rpcli: Text output for "warning" messages is now colorized if
printing to a terminal. printing to a terminal.
* rpcli: On Windows, enable UTF-8 console output if using Windows 7 or later.
* Removed IFUNC support. It's only supported by glibc on Linux (and possibly * Removed IFUNC support. It's only supported by glibc on Linux (and possibly
some of the BSDs), and it adds a lot of complexity. The regular C dispatch some of the BSDs), and it adds a lot of complexity. The regular C dispatch
functions only have a few instructions of overhead in most cases. functions only have a few instructions of overhead in most cases.

View File

@ -11,10 +11,12 @@ video game ROM and disc images.
[![CodeFactor](https://www.codefactor.io/repository/github/gerbilsoft/rom-properties/badge)](https://www.codefactor.io/repository/github/gerbilsoft/rom-properties/overview) [![CodeFactor](https://www.codefactor.io/repository/github/gerbilsoft/rom-properties/badge)](https://www.codefactor.io/repository/github/gerbilsoft/rom-properties/overview)
[![codecov](https://codecov.io/gh/GerbilSoft/rom-properties/graph/badge.svg?token=oIiL6oVPwZ)](https://codecov.io/gh/GerbilSoft/rom-properties) [![codecov](https://codecov.io/gh/GerbilSoft/rom-properties/graph/badge.svg?token=oIiL6oVPwZ)](https://codecov.io/gh/GerbilSoft/rom-properties)
## v2.5 ## v2.5.1
![KDE Dolphin showing J2ME packages.](doc/img/rp-v2.5-kde6.J2ME.png) ![KDE Dolphin showing J2ME packages.](doc/img/rp-v2.5-kde6.J2ME.png)
v2.5.1 is a bugfix release with no significant new features.
Major additions in v2.5 include: Major additions in v2.5 include:
* J2ME packages * J2ME packages
@ -37,7 +39,7 @@ language, check out the [Crowdin project](https://crowdin.com/project/rom-proper
Crowdin project page, file an issue here on GitHub with the requested Crowdin project page, file an issue here on GitHub with the requested
language.) language.)
See [`NEWS.md`](NEWS.md) for a full list of changes in v2.5. See [`NEWS.md`](NEWS.md) for a full list of changes in v2.5.1.
## Feedback ## Feedback

View File

@ -1,5 +1,5 @@
# AppVeyor configuration file. # AppVeyor configuration file.
version: '2.5.0.{build}' version: '2.5.1.{build}'
# Build worker image (VM template) # Build worker image (VM template)
image: image:

View File

@ -17,7 +17,13 @@ IF(NOT USE_INTERNAL_XML)
# Found system PugiXML. # Found system PugiXML.
SET(HAVE_XML 1) SET(HAVE_XML 1)
# NOTE: PugiXML's CMake configuration files don't set pugixml_LIBRARY. # NOTE: PugiXML's CMake configuration files don't set pugixml_LIBRARY.
IF(TARGET pugixml::pugixml)
SET(pugixml_LIBRARY pugixml::pugixml CACHE INTERNAL "PugiXML library" FORCE) SET(pugixml_LIBRARY pugixml::pugixml CACHE INTERNAL "PugiXML library" FORCE)
ELSEIF(TARGET pugixml)
SET(pugixml_LIBRARY pugixml CACHE INTERNAL "PugiXML library" FORCE)
ELSE()
MESSAGE(FATAL_ERROR "Unable to find the correct PugiXML target.")
ENDIF()
ELSE() ELSE()
# System PugiXML was not found. # System PugiXML was not found.
# NOTE: Some older versions, e.g. 1.7-2 (Ubuntu 16.04), lack both # NOTE: Some older versions, e.g. 1.7-2 (Ubuntu 16.04), lack both

View File

@ -111,9 +111,15 @@ IF(CPU_i386 OR CPU_amd64)
ENDIF() ENDIF()
ENDIF(CPU_i386 OR CPU_amd64) ENDIF(CPU_i386 OR CPU_amd64)
IF(CPU_arm OR CPU_arm64 OR CPU_arm64ec) # FIXME: NEON on Ubuntu armhf is complaining when using LTO.
# Disable NEON on armhf for now, except for MSVC.
IF((CPU_arm AND MSVC) OR CPU_arm64 OR CPU_arm64ec)
# Check for arm_neon.h. # Check for arm_neon.h.
# NOTE: Should always be present for arm64, but check anyway. # NOTE: Should always be present for arm64, but check anyway.
INCLUDE(CheckIncludeFile) INCLUDE(CheckIncludeFile)
CHECK_INCLUDE_FILE("arm_neon.h" HAVE_ARM_NEON_H) CHECK_INCLUDE_FILE("arm_neon.h" HAVE_ARM_NEON_H)
ENDIF(CPU_arm OR CPU_arm64 OR CPU_arm64ec)
IF(CPU_arm AND NOT MSVC)
SET(NEON_FLAG "-marm -mfpu=neon")
ENDIF(CPU_arm AND NOT MSVC)
ENDIF((CPU_arm AND MSVC) OR CPU_arm64 OR CPU_arm64ec)

View File

@ -1,5 +1,7 @@
# Build options. # Build options.
OPTION(ENABLE_WERROR "Treat all compile warnings as errors. (Enable for development!)" OFF)
# Platform options. # Platform options.
# NOTE: If a platform is specified but it isn't found, # NOTE: If a platform is specified but it isn't found,
# that plugin will not be built. There doesn't seem to # that plugin will not be built. There doesn't seem to

View File

@ -219,12 +219,12 @@ IF(UNIX AND NOT APPLE)
SET(TMP_HAVE_DT_RELR FALSE) SET(TMP_HAVE_DT_RELR FALSE)
MESSAGE(STATUS "Checking if the system supports DT_RELR - no, needs glibc-2.36 or later") MESSAGE(STATUS "Checking if the system supports DT_RELR - no, needs glibc-2.36 or later")
ENDIF() ENDIF()
UNSET(TMP_HAVE_DT_RELR)
ELSE(_ld_out MATCHES "-z pack-relative-relocs") ELSE(_ld_out MATCHES "-z pack-relative-relocs")
SET(TMP_HAVE_DT_RELR FALSE) SET(TMP_HAVE_DT_RELR FALSE)
MESSAGE(STATUS "Checking if the system supports DT_RELR - no, needs binutils-2.38 or later") MESSAGE(STATUS "Checking if the system supports DT_RELR - no, needs binutils-2.38 or later")
ENDIF(_ld_out MATCHES "-z pack-relative-relocs") ENDIF(_ld_out MATCHES "-z pack-relative-relocs")
SET(HAVE_DT_RELR ${TMP_HAVE_DT_RELR} CACHE INTERNAL "System supports DT_RELR") SET(HAVE_DT_RELR ${TMP_HAVE_DT_RELR} CACHE INTERNAL "System supports DT_RELR")
UNSET(TMP_HAVE_DT_RELR)
ENDIF(NOT DEFINED HAVE_DT_RELR) ENDIF(NOT DEFINED HAVE_DT_RELR)
IF(HAVE_DT_RELR) IF(HAVE_DT_RELR)
@ -274,9 +274,11 @@ IF(CFLAG_OPTIMIZE_FTREE_VECTORIZE)
ENDIF(CFLAG_OPTIMIZE_FTREE_VECTORIZE) ENDIF(CFLAG_OPTIMIZE_FTREE_VECTORIZE)
# Add "-Werror" *after* checking for everything else. # Add "-Werror" *after* checking for everything else.
IF(ENABLE_WERROR)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} -Werror") SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} -Werror")
SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} -Werror") SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} -Werror")
SET(CFLAGS_WNO_ERROR -Wno-error=unknown-pragmas -Wno-error=address -Wno-error=attributes -Wno-error=unused-parameter -Wno-error=unused-but-set-variable -Wno-error=ignored-qualifiers -Wno-error=missing-field-initializers -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=type-limits -Wno-error=empty-body -Wno-error=address-of-packed-member -Wno-error=shift-negative-value -Wno-error=clobbered -Wno-error=overloaded-virtual -Wno-error=header-hygiene)
SET(CFLAGS_WNO_ERROR -Wno-error=unknown-pragmas -Wno-error=address -Wno-error=attributes -Wno-error=unused-parameter -Wno-error=unused-but-set-variable -Wno-error=ignored-qualifiers -Wno-error=missing-field-initializers -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=type-limits -Wno-error=empty-body -Wno-error=address-of-packed-member -Wno-error=shift-negative-value -Wno-error=clobbered -Wno-error=overloaded-virtual -Wno-error=header-hygiene -Wno-error=cast-align -Wno-error=stringop-overread)
FOREACH(FLAG_TEST ${CFLAGS_WNO_ERROR}) FOREACH(FLAG_TEST ${CFLAGS_WNO_ERROR})
# CMake doesn't like certain characters in variable names. # CMake doesn't like certain characters in variable names.
STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}")
@ -288,6 +290,7 @@ FOREACH(FLAG_TEST ${CFLAGS_WNO_ERROR})
ENDIF(CFLAG_${FLAG_TEST_VARNAME}) ENDIF(CFLAG_${FLAG_TEST_VARNAME})
UNSET(CFLAG_${FLAG_TEST_VARNAME}) UNSET(CFLAG_${FLAG_TEST_VARNAME})
ENDFOREACH(FLAG_TEST) ENDFOREACH(FLAG_TEST)
ENDIF(ENABLE_WERROR)
### Debug/Release flags ### ### Debug/Release flags ###
@ -300,10 +303,24 @@ SET(RP_CXX_FLAGS_RELEASE "-O2 -DNDEBUG ${CFLAGS_VECTORIZE}")
SET(RP_C_FLAGS_RELWITHDEBINFO "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}") SET(RP_C_FLAGS_RELWITHDEBINFO "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}")
SET(RP_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}") SET(RP_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb -DNDEBUG ${CFLAGS_VECTORIZE}")
# Enable C++ assertions. (libstdc++ / libc++) # Enable C++ assertions and other hardening options. (libstdc++ / libc++)
# Also enable C++ debug mode. (libstdc++ only) # TODO: Check for the actual C++ runtime being used instead of
# TODO: Only enable GLIBCXX for libstdc++, and LIBCPP for libc++. # assuming libc++ is only used with Clang.
SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_LIBCPP_ENABLE_ASSERTIONS -D_LIBCPP_ENABLE_HARDENED_MODE") SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
# libc++ (clang only)
IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_LIBCPP_ASSERT=1 -D_LIBCPP_DEBUG=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1")
IF(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 16.50)
# clang-17: Use _LIBCPP_HARDENING_MODE.
SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG")
ELSE(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 16.50)
# clang-16 or earlier: Use _LIBCPP_ENABLE_ASSERTIONS.
# NOTE: _LIBCPP_ENABLE_ASSERTIONS causes an error if using clang-17 or later.
SET(RP_CXX_FLAGS_DEBUG "${RP_CXX_FLAGS_DEBUG} -D_LIBCPP_ENABLE_ASSERTIONS=1")
ENDIF(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 16.50)
ENDIF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Unset temporary variables. # Unset temporary variables.
UNSET(CFLAG_OPTIMIZE_DEBUG) UNSET(CFLAG_OPTIMIZE_DEBUG)

View File

@ -23,8 +23,12 @@ ENDIF(NOT CMAKE_SYSTEM_VERSION)
# - C4024: 'function': different types for formal and actual parameter n # - C4024: 'function': different types for formal and actual parameter n
# - C4047: 'function': 'parameter' differs in levels of indirection from 'argument' # - C4047: 'function': 'parameter' differs in levels of indirection from 'argument'
# - C4477: 'function' : format string 'string' requires an argument of type 'type', but variadic argument number has type 'type' # - C4477: 'function' : format string 'string' requires an argument of type 'type', but variadic argument number has type 'type'
SET(RP_C_FLAGS_COMMON "/nologo /W3 /WX /wd4005 /wd4091 /wd4355 /wd4503 /wd4800 /we4013 /we4024 /we4047 /we4477") SET(RP_C_FLAGS_COMMON "/nologo /W3")
SET(RP_CXX_FLAGS_COMMON "${RP_C_FLAGS_COMMON} -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") IF(ENABLE_WERROR)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /WX")
ENDIF(ENABLE_WERROR)
SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /wd4005 /wd4091 /wd4355 /wd4503 /wd4800 /we4013 /we4024 /we4047 /we4477")
SET(RP_CXX_FLAGS_COMMON "${RP_C_FLAGS_COMMON}")
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
# NOTE: /TSAWARE is automatically set for Windows 2000 and later. (as of at least Visual Studio .NET 2003) # NOTE: /TSAWARE is automatically set for Windows 2000 and later. (as of at least Visual Studio .NET 2003)
# NOTE 2: /TSAWARE is not applicable for DLLs. # NOTE 2: /TSAWARE is not applicable for DLLs.

14
debian/changelog vendored
View File

@ -1,3 +1,17 @@
rom-properties (2.5.1-1ppa1~xenial2) xenial; urgency=medium
* Explicitly specify the Tracker API version.
NOTE: This must be updated for each Ubuntu version!
-- David Korth <gerbilsoft@gerbilsoft.com> Sat, 10 May 2025 16:52:48 -0400
rom-properties (2.5.1-1ppa1~xenial1) xenial; urgency=medium
* 2.5.1 release.
-- David Korth <gerbilsoft@gerbilsoft.com> Sat, 10 May 2025 15:29:49 -0400
rom-properties (2.5-1ppa5~xenial4) xenial; urgency=medium rom-properties (2.5-1ppa5~xenial4) xenial; urgency=medium
* 2.5 release. * 2.5 release.

20
debian/control vendored
View File

@ -42,7 +42,7 @@ Vcs-Browser: https://github.com/GerbilSoft/rom-properties
Package: rom-properties-all Package: rom-properties-all
Architecture: any Architecture: any
Depends: ${misc:Depends}, libromdata6, rom-properties-kde4, rom-properties-kf5, rom-properties-xfce, rom-properties-gtk3, rom-properties-cli, rom-properties-tracker, rom-properties-utils, rom-properties-lang, rom-properties-thumbnailer-dbus Depends: ${misc:Depends}, libromdata7, rom-properties-kde4, rom-properties-kf5, rom-properties-xfce, rom-properties-gtk3, rom-properties-cli, rom-properties-tracker, rom-properties-utils, rom-properties-lang, rom-properties-thumbnailer-dbus
Description: ROM Properties Page shell extension (meta package) Description: ROM Properties Page shell extension (meta package)
This shell extension provides thumbnailing and property page functionality This shell extension provides thumbnailing and property page functionality
for ROM images, disc images, and save files for various game consoles, for ROM images, disc images, and save files for various game consoles,
@ -50,9 +50,9 @@ Description: ROM Properties Page shell extension (meta package)
. .
This is a meta-package that installs all rom-properties packages. This is a meta-package that installs all rom-properties packages.
Package: libromdata6 Package: libromdata7
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, rom-properties-data Depends: ${shlibs:Depends}, ${misc:Depends}, rom-properties-data, liblz4-1, liblzo2-2
Description: ROM Properties Page shell extension (shared library) Description: ROM Properties Page shell extension (shared library)
This shell extension provides thumbnailing and property page functionality This shell extension provides thumbnailing and property page functionality
for ROM images, disc images, and save files for various game consoles, for ROM images, disc images, and save files for various game consoles,
@ -63,7 +63,7 @@ Description: ROM Properties Page shell extension (shared library)
Package: rom-properties-kde4 Package: rom-properties-kde4
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata6, rom-properties-utils, rom-properties-xdg Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata7, rom-properties-utils, rom-properties-xdg
Recommends: rom-properties-lang Recommends: rom-properties-lang
Description: ROM Properties Page shell extension (KDE4 UI frontend) Description: ROM Properties Page shell extension (KDE4 UI frontend)
This shell extension provides thumbnailing and property page functionality This shell extension provides thumbnailing and property page functionality
@ -74,7 +74,7 @@ Description: ROM Properties Page shell extension (KDE4 UI frontend)
Package: rom-properties-kio-servicemenus Package: rom-properties-kio-servicemenus
Architecture: all Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata6, rom-properties-utils Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata7, rom-properties-utils
Conflicts: rom-properties-kf5 (<< 2.3) Conflicts: rom-properties-kf5 (<< 2.3)
Replaces: rom-properties-kf5 (<< 2.3) Replaces: rom-properties-kf5 (<< 2.3)
Description: ROM Properties Page shell extension (KF5/KF6 service menus) Description: ROM Properties Page shell extension (KF5/KF6 service menus)
@ -86,7 +86,7 @@ Description: ROM Properties Page shell extension (KF5/KF6 service menus)
Package: rom-properties-kf5 Package: rom-properties-kf5
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata6, rom-properties-utils, rom-properties-xdg, rom-properties-kio-servicemenus Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata7, rom-properties-utils, rom-properties-xdg, rom-properties-kio-servicemenus
Recommends: rom-properties-lang Recommends: rom-properties-lang
Conflicts: rom-properties-kde5 Conflicts: rom-properties-kde5
Replaces: rom-properties-kde5 Replaces: rom-properties-kde5
@ -99,7 +99,7 @@ Description: ROM Properties Page shell extension (KF5 UI frontend)
Package: rom-properties-xfce Package: rom-properties-xfce
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata6, rom-properties-utils, rom-properties-xdg, rom-properties-thumbnailer-dbus Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata7, rom-properties-utils, rom-properties-xdg, rom-properties-thumbnailer-dbus
Recommends: rom-properties-lang, rom-properties-tracker Recommends: rom-properties-lang, rom-properties-tracker
Description: ROM Properties Page shell extension (GTK2 XFCE UI frontend) Description: ROM Properties Page shell extension (GTK2 XFCE UI frontend)
This shell extension provides thumbnailing and property page functionality This shell extension provides thumbnailing and property page functionality
@ -113,7 +113,7 @@ Description: ROM Properties Page shell extension (GTK2 XFCE UI frontend)
Package: rom-properties-gtk3 Package: rom-properties-gtk3
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata6, rom-properties-utils, rom-properties-xdg, rom-properties-thumbnailer-dbus Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata7, rom-properties-utils, rom-properties-xdg, rom-properties-thumbnailer-dbus
Recommends: rom-properties-lang, rom-properties-tracker Recommends: rom-properties-lang, rom-properties-tracker
Conflicts: rom-properties-gnome, rom-properties-mate, rom-properties-cinnamon, rom-properties-gtk3-common Conflicts: rom-properties-gnome, rom-properties-mate, rom-properties-cinnamon, rom-properties-gtk3-common
Replaces: rom-properties-gnome, rom-properties-mate, rom-properties-cinnamon, rom-properties-gtk3-common Replaces: rom-properties-gnome, rom-properties-mate, rom-properties-cinnamon, rom-properties-gtk3-common
@ -132,7 +132,7 @@ Description: ROM Properties Page shell extension (GTK3 UI frontend)
Package: rom-properties-cli Package: rom-properties-cli
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata6 Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata7
Recommends: rom-properties-lang Recommends: rom-properties-lang
Description: ROM Properties Page shell extension (command line version) Description: ROM Properties Page shell extension (command line version)
This shell extension provides thumbnailing and property page functionality This shell extension provides thumbnailing and property page functionality
@ -143,7 +143,7 @@ Description: ROM Properties Page shell extension (command line version)
Package: rom-properties-tracker Package: rom-properties-tracker
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata6 Depends: ${shlibs:Depends}, ${misc:Depends}, libromdata7
Description: ROM Properties Page shell extension (Tracker metadata extractor module) Description: ROM Properties Page shell extension (Tracker metadata extractor module)
This shell extension provides thumbnailing and property page functionality This shell extension provides thumbnailing and property page functionality
for ROM images, disc images, and save files for various game consoles, for ROM images, disc images, and save files for various game consoles,

10
extlib/CMakeLists.txt vendored
View File

@ -189,12 +189,14 @@ SET(USE_INTERNAL_MINIZIP TRUE PARENT_SCOPE)
SET(SKIP_INSTALL_HDR ON) SET(SKIP_INSTALL_HDR ON)
IF(WIN32) IF(WIN32)
SET(USE_INTERNAL_MINIZIP_DLL TRUE PARENT_SCOPE) SET(USE_INTERNAL_MINIZIP_DLL TRUE PARENT_SCOPE)
SET(SKIP_INSTALL_BINARIES ON)
SET(SKIP_INSTALL_LIBRARIES OFF) SET(SKIP_INSTALL_LIBRARIES OFF)
SET(SKIP_INSTALL_ALL OFF) SET(SKIP_INSTALL_ALL OFF)
SET(BUILD_SHARED_LIBS ON) SET(BUILD_SHARED_LIBS ON)
SET(BUILD_STATIC_LIBS OFF) SET(BUILD_STATIC_LIBS OFF)
ELSE() ELSE()
UNSET(USE_INTERNAL_MINIZIP_DLL PARENT_SCOPE) UNSET(USE_INTERNAL_MINIZIP_DLL PARENT_SCOPE)
SET(SKIP_INSTALL_BINARIES ON)
SET(SKIP_INSTALL_LIBRARIES ON) SET(SKIP_INSTALL_LIBRARIES ON)
SET(SKIP_INSTALL_ALL ON) SET(SKIP_INSTALL_ALL ON)
SET(BUILD_SHARED_LIBS OFF) SET(BUILD_SHARED_LIBS OFF)
@ -269,10 +271,10 @@ IF(USE_INTERNAL_XML)
SET(PUGIXML_COMPACT OFF) SET(PUGIXML_COMPACT OFF)
SET(PUGIXML_INSTALL ON) SET(PUGIXML_INSTALL ON)
# TODO: Investigate these. # Disable functionality we don't need.
SET(PUGIXML_NO_XPATH OFF) SET(PUGIXML_NO_XPATH ON)
SET(PUGIXML_NO_STL OFF) SET(PUGIXML_NO_STL ON)
SET(PUGIXML_NO_EXCEPTIONS OFF) SET(PUGIXML_NO_EXCEPTIONS ON)
# Build PugiXML. # Build PugiXML.
ADD_SUBDIRECTORY(pugixml) ADD_SUBDIRECTORY(pugixml)

View File

@ -7,6 +7,7 @@ IndentCaseLabels: false
AlwaysBreakTemplateDeclarations: false AlwaysBreakTemplateDeclarations: false
DerivePointerAlignment: false DerivePointerAlignment: false
AllowShortCaseLabelsOnASingleLine: true AllowShortCaseLabelsOnASingleLine: true
QualifierAlignment: Left
AlignConsecutiveShortCaseStatements: AlignConsecutiveShortCaseStatements:
Enabled: true Enabled: true
AcrossEmptyLines: true AcrossEmptyLines: true

View File

@ -244,8 +244,7 @@ if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
endif () endif ()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/support/cmake")
"${CMAKE_CURRENT_SOURCE_DIR}/support/cmake")
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(JoinPaths) include(JoinPaths)

View File

@ -1,3 +1,103 @@
# 11.2.0 - 2025-05-03
- Added the `s` specifier for `std::error_code`. It allows formatting an error
message as a string. For example:
```c++
#include <fmt/std.h>
int main() {
auto ec = std::make_error_code(std::errc::no_such_file_or_directory);
fmt::print("{:s}\n", ec);
}
```
prints
```
No such file or directory
```
(The actual message is platform-specific.)
- Fixed formatting of `std::chrono::local_time` and `tm`
(https://github.com/fmtlib/fmt/issues/3815,
https://github.com/fmtlib/fmt/issues/4350).
For example ([godbolt](https://www.godbolt.org/z/8o4b1PPn5)):
```c++
#include <fmt/chrono.h>
int main() {
std::chrono::zoned_time zt(
std::chrono::current_zone(),
std::chrono::system_clock::now());
fmt::print("{}", zt.get_local_time());
}
```
is now formatted consistenly across platforms.
- Added diagnostics for cases when timezone information is not available.
For example:
```c++
fmt::print("{:Z}", std::chrono::local_seconds());
```
now gives a compile-time error.
- Deprecated `fmt::localtime` in favor of `std::localtime`.
- Fixed compilation with GCC 15 and C++20 modules enabled
(https://github.com/fmtlib/fmt/pull/4347). Thanks @tkhyn.
- Fixed handling of named arguments in format specs
(https://github.com/fmtlib/fmt/issues/4360,
https://github.com/fmtlib/fmt/pull/4361). Thanks @dinomight.
- Added error reporting for duplicate named arguments
(https://github.com/fmtlib/fmt/pull/4367). Thanks @dinomight.
- Fixed formatting of `long` with `FMT_BUILTIN_TYPES=0`
(https://github.com/fmtlib/fmt/issues/4375,
https://github.com/fmtlib/fmt/issues/4394).
- Optimized `text_style` using bit packing
(https://github.com/fmtlib/fmt/pull/4363). Thanks @LocalSpook.
- Added support for incomplete types (https://github.com/fmtlib/fmt/issues/3180,
https://github.com/fmtlib/fmt/pull/4383). Thanks @LocalSpook.
- Fixed a flush issue in `fmt::print` when using libstdc++
(https://github.com/fmtlib/fmt/issues/4398).
- Fixed `fmt::println` usage with `FMT_ENFORCE_COMPILE_STRING` and legacy
compile-time checks (https://github.com/fmtlib/fmt/pull/4407).
Thanks @madmaxoft.
- Removed legacy header `fmt/core.h` from docs
(https://github.com/fmtlib/fmt/pull/4421,
https://github.com/fmtlib/fmt/pull/4422). Thanks @krzysztofkortas.
- Worked around limitations of `__builtin_strlen` during constant evaluation
(https://github.com/fmtlib/fmt/issues/4423,
https://github.com/fmtlib/fmt/pull/4429). Thanks @BRevzin.
- Worked around a bug in MSVC v141 (https://github.com/fmtlib/fmt/issues/4412,
https://github.com/fmtlib/fmt/pull/4413). Thanks @hirohira9119.
- Removed the `fmt_detail` namespace
(https://github.com/fmtlib/fmt/issues/4324).
- Removed specializations of `std::is_floating_point` in tests
(https://github.com/fmtlib/fmt/issues/4417).
- Fixed a CMake error when setting `CMAKE_MODULE_PATH` in the pedantic mode
(https://github.com/fmtlib/fmt/pull/4426). Thanks @rlalik.
- Updated the Bazel config (https://github.com/fmtlib/fmt/pull/4400).
Thanks @Vertexwahn.
# 11.1.4 - 2025-02-26 # 11.1.4 - 2025-02-26
- Fixed ABI compatibility with earlier 11.x versions on Windows - Fixed ABI compatibility with earlier 11.x versions on Windows

View File

@ -47,7 +47,7 @@ Try {fmt} in [Compiler Explorer](https://godbolt.org/z/8Mx1EW73v).
hundred million integers to strings per hundred million integers to strings per
second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html) second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html)
- Small code size both in terms of source code with the minimum - Small code size both in terms of source code with the minimum
configuration consisting of just three files, `core.h`, `format.h` configuration consisting of just three files, `base.h`, `format.h`
and `format-inl.h`, and compiled code; see [Compile time and code and `format-inl.h`, and compiled code; see [Compile time and code
bloat](#compile-time-and-code-bloat) bloat](#compile-time-and-code-bloat)
- Reliability: the library has an extensive set of - Reliability: the library has an extensive set of
@ -74,7 +74,7 @@ See the [documentation](https://fmt.dev) for more details.
**Print to stdout** ([run](https://godbolt.org/z/Tevcjh)) **Print to stdout** ([run](https://godbolt.org/z/Tevcjh))
``` c++ ``` c++
#include <fmt/core.h> #include <fmt/base.h>
int main() { int main() {
fmt::print("Hello, world!\n"); fmt::print("Hello, world!\n");

View File

@ -1,13 +1,13 @@
This copy of libfmt 11.1.4 is a modified version of the original. This copy of libfmt 11.2.0 is a modified version of the original.
commit 123913715afeb8a437e6388b4473fcc4753e1c9a commit 40626af88bd7df9a5fb80be7b25ac85b122d6c21
Update version Update version
Tag: 11.1.4 Tag: 11.2.0
The following changes have been made to the original: The following changes have been made to the original:
- Removed documentation and test suites. - Removed documentation and test suites.
To obtain the original libfmt-11.1.4, visit: To obtain the original libfmt-11.2.0, visit:
https://github.com/fmtlib/fmt https://github.com/fmtlib/fmt

12
extlib/fmt/doc/api.md vendored
View File

@ -220,7 +220,7 @@ You can also write a formatter for a hierarchy of classes:
```c++ ```c++
// demo.h: // demo.h:
#include <type_traits> #include <type_traits>
#include <fmt/core.h> #include <fmt/format.h>
struct A { struct A {
virtual ~A() {} virtual ~A() {}
@ -403,7 +403,7 @@ All formatting is locale-independent by default. Use the `'L'` format
specifier to insert the appropriate number separator characters from the specifier to insert the appropriate number separator characters from the
locale: locale:
#include <fmt/core.h> #include <fmt/format.h>
#include <locale> #include <locale>
std::locale::global(std::locale("en_US.UTF-8")); std::locale::global(std::locale("en_US.UTF-8"));
@ -473,9 +473,9 @@ chrono-format-specifications).
#include <fmt/chrono.h> #include <fmt/chrono.h>
int main() { int main() {
std::time_t t = std::time(nullptr); auto now = std::chrono::system_clock::now();
fmt::print("The date is {:%Y-%m-%d}.", fmt::localtime(t)); fmt::print("The date is {:%Y-%m-%d}.\n", now);
// Output: The date is 2020-11-07. // Output: The date is 2020-11-07.
// (with 2020-11-07 replaced by the current date) // (with 2020-11-07 replaced by the current date)
@ -488,8 +488,6 @@ chrono-format-specifications).
// Output: strftime-like format: 03:15:30 // Output: strftime-like format: 03:15:30
} }
::: localtime(std::time_t)
::: gmtime(std::time_t) ::: gmtime(std::time_t)
<a id="std-api"></a> <a id="std-api"></a>
@ -580,7 +578,7 @@ performance bottleneck.
`fmt/color.h` provides support for terminal color and text style output. `fmt/color.h` provides support for terminal color and text style output.
::: print(const text_style&, format_string<T...>, T&&...) ::: print(text_style, format_string<T...>, T&&...)
::: fg(detail::color_type) ::: fg(detail::color_type)

View File

@ -122,7 +122,7 @@ hide:
</p> </p>
<p> <p>
The library is highly portable and requires only a minimal <b>subset of The library is highly portable and requires only a minimal <b>subset of
C++11</b> features which are available in GCC 4.9, Clang 3.4, MSVC 19.10 C++11</b> features which are available in GCC 4.9, Clang 3.6, MSVC 19.10
(2017) and later. Newer compiler and standard library features are used (2017) and later. Newer compiler and standard library features are used
if available, and enable additional functionality. if available, and enable additional functionality.
</p> </p>

View File

@ -21,7 +21,7 @@
#endif #endif
// The fmt library version in the form major * 10000 + minor * 100 + patch. // The fmt library version in the form major * 10000 + minor * 100 + patch.
#define FMT_VERSION 110104 #define FMT_VERSION 110200
// Detect compiler versions. // Detect compiler versions.
#if defined(__clang__) && !defined(__ibmxl__) #if defined(__clang__) && !defined(__ibmxl__)
@ -209,20 +209,6 @@
# define FMT_DEPRECATED /* deprecated */ # define FMT_DEPRECATED /* deprecated */
#endif #endif
#ifdef FMT_ALWAYS_INLINE
// Use the provided definition.
#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
# define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
#else
# define FMT_ALWAYS_INLINE inline
#endif
// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
#ifdef NDEBUG
# define FMT_INLINE FMT_ALWAYS_INLINE
#else
# define FMT_INLINE inline
#endif
#if FMT_GCC_VERSION || FMT_CLANG_VERSION #if FMT_GCC_VERSION || FMT_CLANG_VERSION
# define FMT_VISIBILITY(value) __attribute__((visibility(value))) # define FMT_VISIBILITY(value) __attribute__((visibility(value)))
#else #else
@ -249,6 +235,28 @@
# define FMT_MSC_WARNING(...) # define FMT_MSC_WARNING(...)
#endif #endif
// Enable minimal optimizations for more compact code in debug mode.
FMT_PRAGMA_GCC(push_options)
#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
FMT_PRAGMA_GCC(optimize("Og"))
# define FMT_GCC_OPTIMIZED
#endif
FMT_PRAGMA_CLANG(diagnostic push)
#ifdef FMT_ALWAYS_INLINE
// Use the provided definition.
#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
# define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
#else
# define FMT_ALWAYS_INLINE inline
#endif
// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
#if defined(NDEBUG) || defined(FMT_GCC_OPTIMIZED)
# define FMT_INLINE FMT_ALWAYS_INLINE
#else
# define FMT_INLINE inline
#endif
#ifndef FMT_BEGIN_NAMESPACE #ifndef FMT_BEGIN_NAMESPACE
# define FMT_BEGIN_NAMESPACE \ # define FMT_BEGIN_NAMESPACE \
namespace fmt { \ namespace fmt { \
@ -297,13 +305,6 @@
using unused = int[]; \ using unused = int[]; \
(void)unused { 0, (expr, 0)... } (void)unused { 0, (expr, 0)... }
// Enable minimal optimizations for more compact code in debug mode.
FMT_PRAGMA_GCC(push_options)
#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
FMT_PRAGMA_GCC(optimize("Og"))
#endif
FMT_PRAGMA_CLANG(diagnostic push)
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
// Implementations of enable_if_t and other metafunctions for older systems. // Implementations of enable_if_t and other metafunctions for older systems.
@ -325,8 +326,8 @@ using underlying_t = typename std::underlying_type<T>::type;
template <typename T> using decay_t = typename std::decay<T>::type; template <typename T> using decay_t = typename std::decay<T>::type;
using nullptr_t = decltype(nullptr); using nullptr_t = decltype(nullptr);
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500 #if (FMT_GCC_VERSION && FMT_GCC_VERSION < 500) || FMT_MSC_VERSION
// A workaround for gcc 4.9 to make void_t work in a SFINAE context. // A workaround for gcc 4.9 & MSVC v141 to make void_t work in a SFINAE context.
template <typename...> struct void_t_impl { template <typename...> struct void_t_impl {
using type = void; using type = void;
}; };
@ -526,20 +527,20 @@ template <typename Char> class basic_string_view {
constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {} constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
/// Constructs a string reference object from a C string and a size. /// Constructs a string view object from a C string and a size.
constexpr basic_string_view(const Char* s, size_t count) noexcept constexpr basic_string_view(const Char* s, size_t count) noexcept
: data_(s), size_(count) {} : data_(s), size_(count) {}
constexpr basic_string_view(nullptr_t) = delete; constexpr basic_string_view(nullptr_t) = delete;
/// Constructs a string reference object from a C string. /// Constructs a string view object from a C string.
#if FMT_GCC_VERSION #if FMT_GCC_VERSION
FMT_ALWAYS_INLINE FMT_ALWAYS_INLINE
#endif #endif
FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) { FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {
#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION #if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
if (std::is_same<Char, char>::value) { if (std::is_same<Char, char>::value && !detail::is_constant_evaluated()) {
size_ = __builtin_strlen(detail::narrow(s)); size_ = __builtin_strlen(detail::narrow(s)); // strlen is not costexpr.
return; return;
} }
#endif #endif
@ -548,7 +549,7 @@ template <typename Char> class basic_string_view {
size_ = len; size_ = len;
} }
/// Constructs a string reference from a `std::basic_string` or a /// Constructs a string view from a `std::basic_string` or a
/// `std::basic_string_view` object. /// `std::basic_string_view` object.
template <typename S, template <typename S,
FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same< FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same<
@ -585,7 +586,6 @@ template <typename Char> class basic_string_view {
return starts_with(basic_string_view<Char>(s)); return starts_with(basic_string_view<Char>(s));
} }
// Lexicographically compare this string reference to other.
FMT_CONSTEXPR auto compare(basic_string_view other) const -> int { FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
int result = int result =
detail::compare(data_, other.data_, min_of(size_, other.size_)); detail::compare(data_, other.data_, min_of(size_, other.size_));
@ -616,7 +616,7 @@ template <typename Char> class basic_string_view {
using string_view = basic_string_view<char>; using string_view = basic_string_view<char>;
/// Specifies if `T` is an extended character type. Can be specialized by users. // DEPRECATED! Will be merged with is_char and moved to detail.
template <typename T> struct is_xchar : std::false_type {}; template <typename T> struct is_xchar : std::false_type {};
template <> struct is_xchar<wchar_t> : std::true_type {}; template <> struct is_xchar<wchar_t> : std::true_type {};
template <> struct is_xchar<char16_t> : std::true_type {}; template <> struct is_xchar<char16_t> : std::true_type {};
@ -625,7 +625,7 @@ template <> struct is_xchar<char32_t> : std::true_type {};
template <> struct is_xchar<char8_t> : std::true_type {}; template <> struct is_xchar<char8_t> : std::true_type {};
#endif #endif
// DEPRECATED! Will be replaced with an alias to prevent specializations. // Specifies if `T` is a character (code unit) type.
template <typename T> struct is_char : is_xchar<T> {}; template <typename T> struct is_char : is_xchar<T> {};
template <> struct is_char<char> : std::true_type {}; template <> struct is_char<char> : std::true_type {};
@ -1032,6 +1032,11 @@ enum {
struct view {}; struct view {};
template <typename T, typename Enable = std::true_type>
struct is_view : std::false_type {};
template <typename T>
struct is_view<T, bool_constant<sizeof(T) != 0>> : std::is_base_of<view, T> {};
template <typename Char, typename T> struct named_arg; template <typename Char, typename T> struct named_arg;
template <typename T> struct is_named_arg : std::false_type {}; template <typename T> struct is_named_arg : std::false_type {};
template <typename T> struct is_static_named_arg : std::false_type {}; template <typename T> struct is_static_named_arg : std::false_type {};
@ -1064,6 +1069,16 @@ template <typename Char> struct named_arg_info {
int id; int id;
}; };
// named_args is non-const to suppress a bogus -Wmaybe-uninitalized in gcc 13.
template <typename Char>
FMT_CONSTEXPR void check_for_duplicate(named_arg_info<Char>* named_args,
int named_arg_index,
basic_string_view<Char> arg_name) {
for (int i = 0; i < named_arg_index; ++i) {
if (named_args[i].name == arg_name) report_error("duplicate named arg");
}
}
template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)> template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) { void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
++arg_index; ++arg_index;
@ -1071,6 +1086,7 @@ void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)> template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index, void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
int& named_arg_index, const T& arg) { int& named_arg_index, const T& arg) {
check_for_duplicate<Char>(named_args, named_arg_index, arg.name);
named_args[named_arg_index++] = {arg.name, arg_index++}; named_args[named_arg_index++] = {arg.name, arg_index++};
} }
@ -1084,12 +1100,13 @@ template <typename T, typename Char,
FMT_ENABLE_IF(is_static_named_arg<T>::value)> FMT_ENABLE_IF(is_static_named_arg<T>::value)>
FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args, FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,
int& arg_index, int& named_arg_index) { int& arg_index, int& named_arg_index) {
check_for_duplicate<Char>(named_args, named_arg_index, T::name);
named_args[named_arg_index++] = {T::name, arg_index++}; named_args[named_arg_index++] = {T::name, arg_index++};
} }
// To minimize the number of types we need to deal with, long is translated // To minimize the number of types we need to deal with, long is translated
// either to int or to long long depending on its size. // either to int or to long long depending on its size.
enum { long_short = sizeof(long) == sizeof(int) }; enum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES };
using long_type = conditional_t<long_short, int, long long>; using long_type = conditional_t<long_short, int, long long>;
using ulong_type = conditional_t<long_short, unsigned, unsigned long long>; using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
@ -1706,7 +1723,17 @@ class format_string_checker {
-> const Char* { -> const Char* {
context_.advance_to(begin); context_.advance_to(begin);
if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_); if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);
while (begin != end && *begin != '}') ++begin;
// If id is out of range, it means we do not know the type and cannot parse
// the format at compile time. Instead, skip over content until we finish
// the format spec, accounting for any nested replacements.
for (int bracket_count = 0;
begin != end && (bracket_count > 0 || *begin != '}'); ++begin) {
if (*begin == '{')
++bracket_count;
else if (*begin == '}')
--bracket_count;
}
return begin; return begin;
} }
@ -2703,7 +2730,7 @@ template <typename... T> struct fstring {
template <size_t N> template <size_t N>
FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) { FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) {
using namespace detail; using namespace detail;
static_assert(count<(std::is_base_of<view, remove_reference_t<T>>::value && static_assert(count<(is_view<remove_cvref_t<T>>::value &&
std::is_reference<T>::value)...>() == 0, std::is_reference<T>::value)...>() == 0,
"passing views as lvalues is disallowed"); "passing views as lvalues is disallowed");
if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack())); if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));

View File

@ -22,21 +22,6 @@
#include "format.h" #include "format.h"
namespace fmt_detail {
struct time_zone {
template <typename Duration, typename T>
auto to_sys(T)
-> std::chrono::time_point<std::chrono::system_clock, Duration> {
return {};
}
};
template <typename... T> inline auto current_zone(T...) -> time_zone* {
return nullptr;
}
template <typename... T> inline void _tzset(T...) {}
} // namespace fmt_detail
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
// Enable safe chrono durations, unless explicitly disabled. // Enable safe chrono durations, unless explicitly disabled.
@ -435,14 +420,11 @@ auto write(OutputIt out, const std::tm& time, const std::locale& loc,
return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc); return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc);
} }
template <typename Rep1, typename Rep2> template <typename T, typename U>
struct is_same_arithmetic_type using is_similar_arithmetic_type =
: public std::integral_constant<bool, bool_constant<(std::is_integral<T>::value && std::is_integral<U>::value) ||
(std::is_integral<Rep1>::value && (std::is_floating_point<T>::value &&
std::is_integral<Rep2>::value) || std::is_floating_point<U>::value)>;
(std::is_floating_point<Rep1>::value &&
std::is_floating_point<Rep2>::value)> {
};
FMT_NORETURN inline void throw_duration_error() { FMT_NORETURN inline void throw_duration_error() {
FMT_THROW(format_error("cannot format duration")); FMT_THROW(format_error("cannot format duration"));
@ -501,9 +483,9 @@ auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
#endif #endif
} }
template < template <typename To, typename FromRep, typename FromPeriod,
typename To, typename FromRep, typename FromPeriod, FMT_ENABLE_IF(
FMT_ENABLE_IF(!is_same_arithmetic_type<FromRep, typename To::rep>::value)> !is_similar_arithmetic_type<FromRep, typename To::rep>::value)>
auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To { auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
// Mixed integer <-> float cast is not supported by safe_duration_cast. // Mixed integer <-> float cast is not supported by safe_duration_cast.
return std::chrono::duration_cast<To>(from); return std::chrono::duration_cast<To>(from);
@ -519,12 +501,30 @@ auto to_time_t(sys_time<Duration> time_point) -> std::time_t {
.count(); .count();
} }
// Workaround a bug in libstdc++ which sets __cpp_lib_chrono to 201907 without namespace tz {
// providing current_zone(): https://github.com/fmtlib/fmt/issues/4160.
template <typename T> FMT_CONSTEXPR auto has_current_zone() -> bool { // DEPRECATED!
using namespace std::chrono; struct time_zone {
using namespace fmt_detail; template <typename Duration, typename LocalTime>
return !std::is_same<decltype(current_zone()), fmt_detail::time_zone*>::value; auto to_sys(LocalTime) -> sys_time<Duration> {
return {};
}
};
template <typename... T> auto current_zone(T...) -> time_zone* {
return nullptr;
}
template <typename... T> void _tzset(T...) {}
} // namespace tz
// DEPRECATED!
inline void tzset_once() {
static bool init = []() {
using namespace tz;
_tzset();
return false;
}();
ignore_unused(init);
} }
} // namespace detail } // namespace detail
@ -535,7 +535,7 @@ FMT_BEGIN_EXPORT
* expressed in local time. Unlike `std::localtime`, this function is * expressed in local time. Unlike `std::localtime`, this function is
* thread-safe on most platforms. * thread-safe on most platforms.
*/ */
inline auto localtime(std::time_t time) -> std::tm { FMT_DEPRECATED inline auto localtime(std::time_t time) -> std::tm {
struct dispatcher { struct dispatcher {
std::time_t time_; std::time_t time_;
std::tm tm_; std::tm tm_;
@ -572,11 +572,11 @@ inline auto localtime(std::time_t time) -> std::tm {
} }
#if FMT_USE_LOCAL_TIME #if FMT_USE_LOCAL_TIME
template <typename Duration, template <typename Duration>
FMT_ENABLE_IF(detail::has_current_zone<Duration>())> FMT_DEPRECATED auto localtime(std::chrono::local_time<Duration> time)
inline auto localtime(std::chrono::local_time<Duration> time) -> std::tm { -> std::tm {
using namespace std::chrono; using namespace std::chrono;
using namespace fmt_detail; using namespace detail::tz;
return localtime(detail::to_time_t(current_zone()->to_sys<Duration>(time))); return localtime(detail::to_time_t(current_zone()->to_sys<Duration>(time)));
} }
#endif #endif
@ -911,7 +911,14 @@ template <typename Derived> struct null_chrono_spec_handler {
FMT_CONSTEXPR void on_tz_name() { unsupported(); } FMT_CONSTEXPR void on_tz_name() { unsupported(); }
}; };
struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> { class tm_format_checker : public null_chrono_spec_handler<tm_format_checker> {
private:
bool has_timezone_ = false;
public:
constexpr explicit tm_format_checker(bool has_timezone)
: has_timezone_(has_timezone) {}
FMT_NORETURN inline void unsupported() { FMT_NORETURN inline void unsupported() {
FMT_THROW(format_error("no format")); FMT_THROW(format_error("no format"));
} }
@ -949,8 +956,12 @@ struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
FMT_CONSTEXPR void on_24_hour_time() {} FMT_CONSTEXPR void on_24_hour_time() {}
FMT_CONSTEXPR void on_iso_time() {} FMT_CONSTEXPR void on_iso_time() {}
FMT_CONSTEXPR void on_am_pm() {} FMT_CONSTEXPR void on_am_pm() {}
FMT_CONSTEXPR void on_utc_offset(numeric_system) {} FMT_CONSTEXPR void on_utc_offset(numeric_system) {
FMT_CONSTEXPR void on_tz_name() {} if (!has_timezone_) FMT_THROW(format_error("no timezone"));
}
FMT_CONSTEXPR void on_tz_name() {
if (!has_timezone_) FMT_THROW(format_error("no timezone"));
}
}; };
inline auto tm_wday_full_name(int wday) -> const char* { inline auto tm_wday_full_name(int wday) -> const char* {
@ -980,24 +991,27 @@ inline auto tm_mon_short_name(int mon) -> const char* {
} }
template <typename T, typename = void> template <typename T, typename = void>
struct has_member_data_tm_gmtoff : std::false_type {}; struct has_tm_gmtoff : std::false_type {};
template <typename T> template <typename T>
struct has_member_data_tm_gmtoff<T, void_t<decltype(T::tm_gmtoff)>> struct has_tm_gmtoff<T, void_t<decltype(T::tm_gmtoff)>> : std::true_type {};
: std::true_type {};
template <typename T, typename = void> template <typename T, typename = void> struct has_tm_zone : std::false_type {};
struct has_member_data_tm_zone : std::false_type {};
template <typename T> template <typename T>
struct has_member_data_tm_zone<T, void_t<decltype(T::tm_zone)>> struct has_tm_zone<T, void_t<decltype(T::tm_zone)>> : std::true_type {};
: std::true_type {};
inline void tzset_once() { template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>
static bool init = []() { bool set_tm_zone(T& time, char* tz) {
using namespace fmt_detail; time.tm_zone = tz;
_tzset(); return true;
}
template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>
bool set_tm_zone(T&, char*) {
return false; return false;
}(); }
ignore_unused(init);
inline char* utc() {
static char tz[] = "UTC";
return tz;
} }
// Converts value to Int and checks that it's in the range [0, upper). // Converts value to Int and checks that it's in the range [0, upper).
@ -1005,7 +1019,7 @@ template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline auto to_nonnegative_int(T value, Int upper) -> Int { inline auto to_nonnegative_int(T value, Int upper) -> Int {
if (!std::is_unsigned<Int>::value && if (!std::is_unsigned<Int>::value &&
(value < 0 || to_unsigned(value) > to_unsigned(upper))) { (value < 0 || to_unsigned(value) > to_unsigned(upper))) {
FMT_THROW(fmt::format_error("chrono value is out of range")); FMT_THROW(format_error("chrono value is out of range"));
} }
return static_cast<Int>(value); return static_cast<Int>(value);
} }
@ -1090,7 +1104,7 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {
// Format subseconds which are given as a floating point type with an // Format subseconds which are given as a floating point type with an
// appropriate number of digits. We cannot pass the Duration here, as we // appropriate number of digits. We cannot pass the Duration here, as we
// explicitly need to pass the Rep value in the chrono_formatter. // explicitly need to pass the Rep value in the duration_formatter.
template <typename Duration> template <typename Duration>
void write_floating_seconds(memory_buffer& buf, Duration duration, void write_floating_seconds(memory_buffer& buf, Duration duration,
int num_fractional_digits = -1) { int num_fractional_digits = -1) {
@ -1124,7 +1138,7 @@ class tm_writer {
static constexpr int days_per_week = 7; static constexpr int days_per_week = 7;
const std::locale& loc_; const std::locale& loc_;
const bool is_classic_; bool is_classic_;
OutputIt out_; OutputIt out_;
const Duration* subsecs_; const Duration* subsecs_;
const std::tm& tm_; const std::tm& tm_;
@ -1160,8 +1174,8 @@ class tm_writer {
} }
auto tm_hour12() const noexcept -> int { auto tm_hour12() const noexcept -> int {
const auto h = tm_hour(); auto h = tm_hour();
const auto z = h < 12 ? h : h - 12; auto z = h < 12 ? h : h - 12;
return z == 0 ? 12 : z; return z == 0 ? 12 : z;
} }
@ -1177,11 +1191,11 @@ class tm_writer {
// Algorithm: https://en.wikipedia.org/wiki/ISO_week_date. // Algorithm: https://en.wikipedia.org/wiki/ISO_week_date.
auto iso_year_weeks(long long curr_year) const noexcept -> int { auto iso_year_weeks(long long curr_year) const noexcept -> int {
const auto prev_year = curr_year - 1; auto prev_year = curr_year - 1;
const auto curr_p = auto curr_p =
(curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) % (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) %
days_per_week; days_per_week;
const auto prev_p = auto prev_p =
(prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) % (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) %
days_per_week; days_per_week;
return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0); return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0);
@ -1191,15 +1205,15 @@ class tm_writer {
days_per_week; days_per_week;
} }
auto tm_iso_week_year() const noexcept -> long long { auto tm_iso_week_year() const noexcept -> long long {
const auto year = tm_year(); auto year = tm_year();
const auto w = iso_week_num(tm_yday(), tm_wday()); auto w = iso_week_num(tm_yday(), tm_wday());
if (w < 1) return year - 1; if (w < 1) return year - 1;
if (w > iso_year_weeks(year)) return year + 1; if (w > iso_year_weeks(year)) return year + 1;
return year; return year;
} }
auto tm_iso_week_of_year() const noexcept -> int { auto tm_iso_week_of_year() const noexcept -> int {
const auto year = tm_year(); auto year = tm_year();
const auto w = iso_week_num(tm_yday(), tm_wday()); auto w = iso_week_num(tm_yday(), tm_wday());
if (w < 1) return iso_year_weeks(year - 1); if (w < 1) return iso_year_weeks(year - 1);
if (w > iso_year_weeks(year)) return 1; if (w > iso_year_weeks(year)) return 1;
return w; return w;
@ -1236,9 +1250,8 @@ class tm_writer {
uint32_or_64_or_128_t<long long> n = to_unsigned(year); uint32_or_64_or_128_t<long long> n = to_unsigned(year);
const int num_digits = count_digits(n); const int num_digits = count_digits(n);
if (negative && pad == pad_type::zero) *out_++ = '-'; if (negative && pad == pad_type::zero) *out_++ = '-';
if (width > num_digits) { if (width > num_digits)
out_ = detail::write_padding(out_, pad, width - num_digits); out_ = detail::write_padding(out_, pad, width - num_digits);
}
if (negative && pad != pad_type::zero) *out_++ = '-'; if (negative && pad != pad_type::zero) *out_++ = '-';
out_ = format_decimal<Char>(out_, n, num_digits); out_ = format_decimal<Char>(out_, n, num_digits);
} }
@ -1259,45 +1272,22 @@ class tm_writer {
write2(static_cast<int>(offset % 60)); write2(static_cast<int>(offset % 60));
} }
template <typename T, FMT_ENABLE_IF(has_member_data_tm_gmtoff<T>::value)> template <typename T, FMT_ENABLE_IF(has_tm_gmtoff<T>::value)>
void format_utc_offset_impl(const T& tm, numeric_system ns) { void format_utc_offset(const T& tm, numeric_system ns) {
write_utc_offset(tm.tm_gmtoff, ns); write_utc_offset(tm.tm_gmtoff, ns);
} }
template <typename T, FMT_ENABLE_IF(!has_member_data_tm_gmtoff<T>::value)> template <typename T, FMT_ENABLE_IF(!has_tm_gmtoff<T>::value)>
void format_utc_offset_impl(const T& tm, numeric_system ns) { void format_utc_offset(const T&, numeric_system ns) {
#if defined(_WIN32) && defined(_UCRT) write_utc_offset(0, ns);
tzset_once();
long offset = 0;
_get_timezone(&offset);
if (tm.tm_isdst) {
long dstbias = 0;
_get_dstbias(&dstbias);
offset += dstbias;
}
write_utc_offset(-offset, ns);
#else
if (ns == numeric_system::standard) return format_localized('z');
// Extract timezone offset from timezone conversion functions.
std::tm gtm = tm;
std::time_t gt = std::mktime(&gtm);
std::tm ltm = gmtime(gt);
std::time_t lt = std::mktime(&ltm);
long long offset = gt - lt;
write_utc_offset(offset, ns);
#endif
} }
template <typename T, FMT_ENABLE_IF(has_member_data_tm_zone<T>::value)> template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>
void format_tz_name_impl(const T& tm) { void format_tz_name(const T& tm) {
if (is_classic_)
out_ = write_tm_str<Char>(out_, tm.tm_zone, loc_); out_ = write_tm_str<Char>(out_, tm.tm_zone, loc_);
else
format_localized('Z');
} }
template <typename T, FMT_ENABLE_IF(!has_member_data_tm_zone<T>::value)> template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>
void format_tz_name_impl(const T&) { void format_tz_name(const T&) {
format_localized('Z'); out_ = std::copy_n(utc(), 3, out_);
} }
void format_localized(char format, char modifier = 0) { void format_localized(char format, char modifier = 0) {
@ -1408,8 +1398,8 @@ class tm_writer {
out_ = copy<Char>(std::begin(buf) + offset, std::end(buf), out_); out_ = copy<Char>(std::begin(buf) + offset, std::end(buf), out_);
} }
void on_utc_offset(numeric_system ns) { format_utc_offset_impl(tm_, ns); } void on_utc_offset(numeric_system ns) { format_utc_offset(tm_, ns); }
void on_tz_name() { format_tz_name_impl(tm_); } void on_tz_name() { format_tz_name(tm_); }
void on_year(numeric_system ns, pad_type pad) { void on_year(numeric_system ns, pad_type pad) {
if (is_classic_ || ns == numeric_system::standard) if (is_classic_ || ns == numeric_system::standard)
@ -1483,11 +1473,10 @@ class tm_writer {
void on_day_of_year(pad_type pad) { void on_day_of_year(pad_type pad) {
auto yday = tm_yday() + 1; auto yday = tm_yday() + 1;
auto digit1 = yday / 100; auto digit1 = yday / 100;
if (digit1 != 0) { if (digit1 != 0)
write1(digit1); write1(digit1);
} else { else
out_ = detail::write_padding(out_, pad); out_ = detail::write_padding(out_, pad);
}
write2(yday % 100, pad); write2(yday % 100, pad);
} }
@ -1624,18 +1613,16 @@ template <typename Rep, typename Period,
FMT_ENABLE_IF(std::is_integral<Rep>::value)> FMT_ENABLE_IF(std::is_integral<Rep>::value)>
inline auto get_milliseconds(std::chrono::duration<Rep, Period> d) inline auto get_milliseconds(std::chrono::duration<Rep, Period> d)
-> std::chrono::duration<Rep, std::milli> { -> std::chrono::duration<Rep, std::milli> {
// this may overflow and/or the result may not fit in the // This may overflow and/or the result may not fit in the target type.
// target type.
#if FMT_SAFE_DURATION_CAST #if FMT_SAFE_DURATION_CAST
using CommonSecondsType = using common_seconds_type =
typename std::common_type<decltype(d), std::chrono::seconds>::type; typename std::common_type<decltype(d), std::chrono::seconds>::type;
const auto d_as_common = detail::duration_cast<CommonSecondsType>(d); auto d_as_common = detail::duration_cast<common_seconds_type>(d);
const auto d_as_whole_seconds = auto d_as_whole_seconds =
detail::duration_cast<std::chrono::seconds>(d_as_common); detail::duration_cast<std::chrono::seconds>(d_as_common);
// this conversion should be nonproblematic // This conversion should be nonproblematic.
const auto diff = d_as_common - d_as_whole_seconds; auto diff = d_as_common - d_as_whole_seconds;
const auto ms = auto ms = detail::duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
detail::duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
return ms; return ms;
#else #else
auto s = detail::duration_cast<std::chrono::seconds>(d); auto s = detail::duration_cast<std::chrono::seconds>(d);
@ -1707,32 +1694,28 @@ class get_locale {
} }
}; };
template <typename FormatContext, typename OutputIt, typename Rep, template <typename Char, typename Rep, typename Period>
typename Period> struct duration_formatter {
struct chrono_formatter { using iterator = basic_appender<Char>;
FormatContext& context; iterator out;
OutputIt out;
int precision;
bool localized = false;
// rep is unsigned to avoid overflow. // rep is unsigned to avoid overflow.
using rep = using rep =
conditional_t<std::is_integral<Rep>::value && sizeof(Rep) < sizeof(int), conditional_t<std::is_integral<Rep>::value && sizeof(Rep) < sizeof(int),
unsigned, typename make_unsigned_or_unchanged<Rep>::type>; unsigned, typename make_unsigned_or_unchanged<Rep>::type>;
rep val; rep val;
int precision;
locale_ref locale;
bool localized = false;
using seconds = std::chrono::duration<rep>; using seconds = std::chrono::duration<rep>;
seconds s; seconds s;
using milliseconds = std::chrono::duration<rep, std::milli>; using milliseconds = std::chrono::duration<rep, std::milli>;
bool negative; bool negative;
using char_type = typename FormatContext::char_type; using tm_writer_type = tm_writer<iterator, Char>;
using tm_writer_type = tm_writer<OutputIt, char_type>;
chrono_formatter(FormatContext& ctx, OutputIt o, duration_formatter(iterator o, std::chrono::duration<Rep, Period> d,
std::chrono::duration<Rep, Period> d) locale_ref loc)
: context(ctx), : out(o), val(static_cast<rep>(d.count())), locale(loc), negative(false) {
out(o),
val(static_cast<rep>(d.count())),
negative(false) {
if (d.count() < 0) { if (d.count() < 0) {
val = 0 - val; val = 0 - val;
negative = true; negative = true;
@ -1746,19 +1729,16 @@ struct chrono_formatter {
// returns true if nan or inf, writes to out. // returns true if nan or inf, writes to out.
auto handle_nan_inf() -> bool { auto handle_nan_inf() -> bool {
if (isfinite(val)) { if (isfinite(val)) return false;
return false;
}
if (isnan(val)) { if (isnan(val)) {
write_nan(); write_nan();
return true; return true;
} }
// must be +-inf // must be +-inf
if (val > 0) { if (val > 0)
write_pinf(); std::copy_n("inf", 3, out);
} else { else
write_ninf(); std::copy_n("-inf", 4, out);
}
return true; return true;
} }
@ -1786,11 +1766,10 @@ struct chrono_formatter {
} }
void write_sign() { void write_sign() {
if (negative) { if (!negative) return;
*out++ = '-'; *out++ = '-';
negative = false; negative = false;
} }
}
void write(Rep value, int width, pad_type pad = pad_type::zero) { void write(Rep value, int width, pad_type pad = pad_type::zero) {
write_sign(); write_sign();
@ -1801,24 +1780,22 @@ struct chrono_formatter {
if (width > num_digits) { if (width > num_digits) {
out = detail::write_padding(out, pad, width - num_digits); out = detail::write_padding(out, pad, width - num_digits);
} }
out = format_decimal<char_type>(out, n, num_digits); out = format_decimal<Char>(out, n, num_digits);
} }
void write_nan() { std::copy_n("nan", 3, out); } void write_nan() { std::copy_n("nan", 3, out); }
void write_pinf() { std::copy_n("inf", 3, out); }
void write_ninf() { std::copy_n("-inf", 4, out); }
template <typename Callback, typename... Args> template <typename Callback, typename... Args>
void format_tm(const tm& time, Callback cb, Args... args) { void format_tm(const tm& time, Callback cb, Args... args) {
if (isnan(val)) return write_nan(); if (isnan(val)) return write_nan();
get_locale loc(localized, context.locale()); get_locale loc(localized, locale);
auto w = tm_writer_type(loc, out, time); auto w = tm_writer_type(loc, out, time);
(w.*cb)(args...); (w.*cb)(args...);
out = w.out(); out = w.out();
} }
void on_text(const char_type* begin, const char_type* end) { void on_text(const Char* begin, const Char* end) {
copy<char_type>(begin, end, out); copy<Char>(begin, end, out);
} }
// These are not implemented because durations don't have date information. // These are not implemented because durations don't have date information.
@ -1888,13 +1865,12 @@ struct chrono_formatter {
write_floating_seconds(buf, std::chrono::duration<rep, Period>(val), write_floating_seconds(buf, std::chrono::duration<rep, Period>(val),
precision); precision);
if (negative) *out++ = '-'; if (negative) *out++ = '-';
if (buf.size() < 2 || buf[1] == '.') { if (buf.size() < 2 || buf[1] == '.')
out = detail::write_padding(out, pad); out = detail::write_padding(out, pad);
} out = copy<Char>(buf.begin(), buf.end(), out);
out = copy<char_type>(buf.begin(), buf.end(), out);
} else { } else {
write(second(), 2, pad); write(second(), 2, pad);
write_fractional_seconds<char_type>( write_fractional_seconds<Char>(
out, std::chrono::duration<rep, Period>(val), precision); out, std::chrono::duration<rep, Period>(val), precision);
} }
return; return;
@ -1936,12 +1912,10 @@ struct chrono_formatter {
void on_duration_value() { void on_duration_value() {
if (handle_nan_inf()) return; if (handle_nan_inf()) return;
write_sign(); write_sign();
out = format_duration_value<char_type>(out, val, precision); out = format_duration_value<Char>(out, val, precision);
} }
void on_duration_unit() { void on_duration_unit() { out = format_duration_unit<Char, Period>(out); }
out = format_duration_unit<char_type, Period>(out);
}
}; };
} // namespace detail } // namespace detail
@ -2011,12 +1985,11 @@ class year_month_day {
constexpr auto month() const noexcept -> fmt::month { return month_; } constexpr auto month() const noexcept -> fmt::month { return month_; }
constexpr auto day() const noexcept -> fmt::day { return day_; } constexpr auto day() const noexcept -> fmt::day { return day_; }
}; };
#endif #endif // __cpp_lib_chrono >= 201907
template <typename Char> template <typename Char>
struct formatter<weekday, Char> : private formatter<std::tm, Char> { struct formatter<weekday, Char> : private formatter<std::tm, Char> {
private: private:
bool localized_ = false;
bool use_tm_formatter_ = false; bool use_tm_formatter_ = false;
public: public:
@ -2024,8 +1997,7 @@ struct formatter<weekday, Char> : private formatter<std::tm, Char> {
auto it = ctx.begin(), end = ctx.end(); auto it = ctx.begin(), end = ctx.end();
if (it != end && *it == 'L') { if (it != end && *it == 'L') {
++it; ++it;
localized_ = true; this->set_localized();
return it;
} }
use_tm_formatter_ = it != end && *it != '}'; use_tm_formatter_ = it != end && *it != '}';
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it; return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
@ -2036,7 +2008,7 @@ struct formatter<weekday, Char> : private formatter<std::tm, Char> {
auto time = std::tm(); auto time = std::tm();
time.tm_wday = static_cast<int>(wd.c_encoding()); time.tm_wday = static_cast<int>(wd.c_encoding());
if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx); if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
detail::get_locale loc(localized_, ctx.locale()); detail::get_locale loc(this->localized(), ctx.locale());
auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time); auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
w.on_abbr_weekday(); w.on_abbr_weekday();
return w.out(); return w.out();
@ -2070,7 +2042,6 @@ struct formatter<day, Char> : private formatter<std::tm, Char> {
template <typename Char> template <typename Char>
struct formatter<month, Char> : private formatter<std::tm, Char> { struct formatter<month, Char> : private formatter<std::tm, Char> {
private: private:
bool localized_ = false;
bool use_tm_formatter_ = false; bool use_tm_formatter_ = false;
public: public:
@ -2078,8 +2049,7 @@ struct formatter<month, Char> : private formatter<std::tm, Char> {
auto it = ctx.begin(), end = ctx.end(); auto it = ctx.begin(), end = ctx.end();
if (it != end && *it == 'L') { if (it != end && *it == 'L') {
++it; ++it;
localized_ = true; this->set_localized();
return it;
} }
use_tm_formatter_ = it != end && *it != '}'; use_tm_formatter_ = it != end && *it != '}';
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it; return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
@ -2090,7 +2060,7 @@ struct formatter<month, Char> : private formatter<std::tm, Char> {
auto time = std::tm(); auto time = std::tm();
time.tm_mon = static_cast<int>(static_cast<unsigned>(m)) - 1; time.tm_mon = static_cast<int>(static_cast<unsigned>(m)) - 1;
if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx); if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
detail::get_locale loc(localized_, ctx.locale()); detail::get_locale loc(this->localized(), ctx.locale());
auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time); auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
w.on_abbr_month(); w.on_abbr_month();
return w.out(); return w.out();
@ -2154,7 +2124,6 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
format_specs specs_; format_specs specs_;
detail::arg_ref<Char> width_ref_; detail::arg_ref<Char> width_ref_;
detail::arg_ref<Char> precision_ref_; detail::arg_ref<Char> precision_ref_;
bool localized_ = false;
basic_string_view<Char> fmt_; basic_string_view<Char> fmt_;
public: public:
@ -2177,7 +2146,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
it = detail::parse_precision(it, end, specs_, precision_ref_, ctx); it = detail::parse_precision(it, end, specs_, precision_ref_, ctx);
} }
if (it != end && *it == 'L') { if (it != end && *it == 'L') {
localized_ = true; specs_.set_localized();
++it; ++it;
} }
end = detail::parse_chrono_format(it, end, checker); end = detail::parse_chrono_format(it, end, checker);
@ -2204,11 +2173,10 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
out = detail::format_duration_value<Char>(out, d.count(), precision); out = detail::format_duration_value<Char>(out, d.count(), precision);
detail::format_duration_unit<Char, Period>(out); detail::format_duration_unit<Char, Period>(out);
} else { } else {
using chrono_formatter = auto f =
detail::chrono_formatter<FormatContext, decltype(out), Rep, Period>; detail::duration_formatter<Char, Rep, Period>(out, d, ctx.locale());
auto f = chrono_formatter(ctx, out, d);
f.precision = precision; f.precision = precision;
f.localized = localized_; f.localized = specs_.localized();
detail::parse_chrono_format(begin, end, f); detail::parse_chrono_format(begin, end, f);
} }
return detail::write( return detail::write(
@ -2220,30 +2188,15 @@ template <typename Char> struct formatter<std::tm, Char> {
private: private:
format_specs specs_; format_specs specs_;
detail::arg_ref<Char> width_ref_; detail::arg_ref<Char> width_ref_;
basic_string_view<Char> fmt_ =
detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
protected: protected:
basic_string_view<Char> fmt_; auto localized() const -> bool { return specs_.localized(); }
FMT_CONSTEXPR void set_localized() { specs_.set_localized(); }
template <typename Duration, typename FormatContext> FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx, bool has_timezone)
auto do_format(const std::tm& tm, FormatContext& ctx, -> const Char* {
const Duration* subsecs) const -> decltype(ctx.out()) {
auto specs = specs_;
auto buf = basic_memory_buffer<Char>();
auto out = basic_appender<Char>(buf);
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
ctx);
auto loc_ref = ctx.locale();
detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
auto w =
detail::tm_writer<decltype(out), Char, Duration>(loc, out, tm, subsecs);
detail::parse_chrono_format(fmt_.begin(), fmt_.end(), w);
return detail::write(
ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
}
public:
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
auto it = ctx.begin(), end = ctx.end(); auto it = ctx.begin(), end = ctx.end();
if (it == end || *it == '}') return it; if (it == end || *it == '}') return it;
@ -2256,12 +2209,41 @@ template <typename Char> struct formatter<std::tm, Char> {
if (it == end) return it; if (it == end) return it;
} }
end = detail::parse_chrono_format(it, end, detail::tm_format_checker()); if (*it == 'L') {
specs_.set_localized();
++it;
}
end = detail::parse_chrono_format(it, end,
detail::tm_format_checker(has_timezone));
// Replace the default format string only if the new spec is not empty. // Replace the default format string only if the new spec is not empty.
if (end != it) fmt_ = {it, detail::to_unsigned(end - it)}; if (end != it) fmt_ = {it, detail::to_unsigned(end - it)};
return end; return end;
} }
template <typename Duration, typename FormatContext>
auto do_format(const std::tm& tm, FormatContext& ctx,
const Duration* subsecs) const -> decltype(ctx.out()) {
auto specs = specs_;
auto buf = basic_memory_buffer<Char>();
auto out = basic_appender<Char>(buf);
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
ctx);
auto loc_ref = specs.localized() ? ctx.locale() : detail::locale_ref();
detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
auto w = detail::tm_writer<basic_appender<Char>, Char, Duration>(
loc, out, tm, subsecs);
detail::parse_chrono_format(fmt_.begin(), fmt_.end(), w);
return detail::write(
ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
}
public:
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return do_parse(ctx, detail::has_tm_gmtoff<std::tm>::value);
}
template <typename FormatContext> template <typename FormatContext>
auto format(const std::tm& tm, FormatContext& ctx) const auto format(const std::tm& tm, FormatContext& ctx) const
-> decltype(ctx.out()) { -> decltype(ctx.out()) {
@ -2269,10 +2251,11 @@ template <typename Char> struct formatter<std::tm, Char> {
} }
}; };
// DEPRECATED! Reversed order of template parameters.
template <typename Char, typename Duration> template <typename Char, typename Duration>
struct formatter<sys_time<Duration>, Char> : formatter<std::tm, Char> { struct formatter<sys_time<Duration>, Char> : private formatter<std::tm, Char> {
FMT_CONSTEXPR formatter() { FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
this->fmt_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>(); return this->do_parse(ctx, true);
} }
template <typename FormatContext> template <typename FormatContext>
@ -2283,6 +2266,7 @@ struct formatter<sys_time<Duration>, Char> : formatter<std::tm, Char> {
if (detail::const_check( if (detail::const_check(
period::num == 1 && period::den == 1 && period::num == 1 && period::den == 1 &&
!std::is_floating_point<typename Duration::rep>::value)) { !std::is_floating_point<typename Duration::rep>::value)) {
detail::set_tm_zone(tm, detail::utc());
return formatter<std::tm, Char>::format(tm, ctx); return formatter<std::tm, Char>::format(tm, ctx);
} }
Duration epoch = val.time_since_epoch(); Duration epoch = val.time_since_epoch();
@ -2290,11 +2274,13 @@ struct formatter<sys_time<Duration>, Char> : formatter<std::tm, Char> {
epoch - detail::duration_cast<std::chrono::seconds>(epoch)); epoch - detail::duration_cast<std::chrono::seconds>(epoch));
if (subsecs.count() < 0) { if (subsecs.count() < 0) {
auto second = detail::duration_cast<Duration>(std::chrono::seconds(1)); auto second = detail::duration_cast<Duration>(std::chrono::seconds(1));
if (tm.tm_sec != 0) if (tm.tm_sec != 0) {
--tm.tm_sec; --tm.tm_sec;
else } else {
tm = gmtime(val - second); tm = gmtime(val - second);
subsecs += detail::duration_cast<Duration>(std::chrono::seconds(1)); detail::set_tm_zone(tm, detail::utc());
}
subsecs += second;
} }
return formatter<std::tm, Char>::do_format(tm, ctx, &subsecs); return formatter<std::tm, Char>::do_format(tm, ctx, &subsecs);
} }
@ -2312,23 +2298,29 @@ struct formatter<utc_time<Duration>, Char>
}; };
template <typename Duration, typename Char> template <typename Duration, typename Char>
struct formatter<local_time<Duration>, Char> : formatter<std::tm, Char> { struct formatter<local_time<Duration>, Char>
FMT_CONSTEXPR formatter() { : private formatter<std::tm, Char> {
this->fmt_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>(); FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return this->do_parse(ctx, false);
} }
template <typename FormatContext> template <typename FormatContext>
auto format(local_time<Duration> val, FormatContext& ctx) const auto format(local_time<Duration> val, FormatContext& ctx) const
-> decltype(ctx.out()) { -> decltype(ctx.out()) {
auto time_since_epoch = val.time_since_epoch();
auto seconds_since_epoch =
detail::duration_cast<std::chrono::seconds>(time_since_epoch);
// Use gmtime to prevent time zone conversion since local_time has an
// unspecified time zone.
std::tm t = gmtime(seconds_since_epoch.count());
using period = typename Duration::period; using period = typename Duration::period;
if (period::num == 1 && period::den == 1 && if (period::num == 1 && period::den == 1 &&
!std::is_floating_point<typename Duration::rep>::value) { !std::is_floating_point<typename Duration::rep>::value) {
return formatter<std::tm, Char>::format(localtime(val), ctx); return formatter<std::tm, Char>::format(t, ctx);
} }
auto epoch = val.time_since_epoch(); auto subsecs =
auto subsecs = detail::duration_cast<Duration>( detail::duration_cast<Duration>(time_since_epoch - seconds_since_epoch);
epoch - detail::duration_cast<std::chrono::seconds>(epoch)); return formatter<std::tm, Char>::do_format(t, ctx, &subsecs);
return formatter<std::tm, Char>::do_format(localtime(val), ctx, &subsecs);
} }
}; };

View File

@ -190,11 +190,11 @@ enum class emphasis : uint8_t {
// rgb is a struct for red, green and blue colors. // rgb is a struct for red, green and blue colors.
// Using the name "rgb" makes some editors show the color in a tooltip. // Using the name "rgb" makes some editors show the color in a tooltip.
struct rgb { struct rgb {
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {} constexpr rgb() : r(0), g(0), b(0) {}
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {} constexpr rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
FMT_CONSTEXPR rgb(uint32_t hex) constexpr rgb(uint32_t hex)
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {} : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
FMT_CONSTEXPR rgb(color hex) constexpr rgb(color hex)
: r((uint32_t(hex) >> 16) & 0xFF), : r((uint32_t(hex) >> 16) & 0xFF),
g((uint32_t(hex) >> 8) & 0xFF), g((uint32_t(hex) >> 8) & 0xFF),
b(uint32_t(hex) & 0xFF) {} b(uint32_t(hex) & 0xFF) {}
@ -205,97 +205,135 @@ struct rgb {
namespace detail { namespace detail {
// color is a struct of either a rgb color or a terminal color. // A bit-packed variant of an RGB color, a terminal color, or unset color.
// see text_style for the bit-packing scheme.
struct color_type { struct color_type {
FMT_CONSTEXPR color_type() noexcept : is_rgb(), value{} {} constexpr color_type() noexcept = default;
FMT_CONSTEXPR color_type(color rgb_color) noexcept : is_rgb(true), value{} { constexpr color_type(color rgb_color) noexcept
value.rgb_color = static_cast<uint32_t>(rgb_color); : value_(static_cast<uint32_t>(rgb_color) | (1 << 24)) {}
constexpr color_type(rgb rgb_color) noexcept
: color_type(static_cast<color>(
(static_cast<uint32_t>(rgb_color.r) << 16) |
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b)) {}
constexpr color_type(terminal_color term_color) noexcept
: value_(static_cast<uint32_t>(term_color) | (3 << 24)) {}
constexpr auto is_terminal_color() const noexcept -> bool {
return (value_ & (1 << 25)) != 0;
} }
FMT_CONSTEXPR color_type(rgb rgb_color) noexcept : is_rgb(true), value{} {
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) | constexpr auto value() const noexcept -> uint32_t {
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b; return value_ & 0xFFFFFF;
} }
FMT_CONSTEXPR color_type(terminal_color term_color) noexcept
: is_rgb(), value{} { constexpr color_type(uint32_t value) noexcept : value_(value) {}
value.term_color = static_cast<uint8_t>(term_color);
} uint32_t value_ = 0;
bool is_rgb;
union color_union {
uint8_t term_color;
uint32_t rgb_color;
} value;
}; };
} // namespace detail } // namespace detail
/// A text style consisting of foreground and background colors and emphasis. /// A text style consisting of foreground and background colors and emphasis.
class text_style { class text_style {
// The information is packed as follows:
// ┌──┐
// │ 0│─┐
// │..│ ├── foreground color value
// │23│─┘
// ├──┤
// │24│─┬── discriminator for the above value. 00 if unset, 01 if it's
// │25│─┘ an RGB color, or 11 if it's a terminal color (10 is unused)
// ├──┤
// │26│──── overflow bit, always zero (see below)
// ├──┤
// │27│─┐
// │..│ │
// │50│ │
// ├──┤ │
// │51│ ├── background color (same format as the foreground color)
// │52│ │
// ├──┤ │
// │53│─┘
// ├──┤
// │54│─┐
// │..│ ├── emphases
// │61│─┘
// ├──┤
// │62│─┬── unused
// │63│─┘
// └──┘
// The overflow bits are there to make operator|= efficient.
// When ORing, we must throw if, for either the foreground or background,
// one style specifies a terminal color and the other specifies any color
// (terminal or RGB); in other words, if one discriminator is 11 and the
// other is 11 or 01.
//
// We do that check by adding the styles. Consider what adding does to each
// possible pair of discriminators:
// 00 + 00 = 000
// 01 + 00 = 001
// 11 + 00 = 011
// 01 + 01 = 010
// 11 + 01 = 100 (!!)
// 11 + 11 = 110 (!!)
// In the last two cases, the ones we want to catch, the third bit——the
// overflow bit——is set. Bingo.
//
// We must take into account the possible carry bit from the bits
// before the discriminator. The only potentially problematic case is
// 11 + 00 = 011 (a carry bit would make it 100, not good!), but a carry
// bit is impossible in that case, because 00 (unset color) means the
// 24 bits that precede the discriminator are all zero.
//
// This test can be applied to both colors simultaneously.
public: public:
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
: set_foreground_color(), set_background_color(), ems(em) {} : style_(static_cast<uint64_t>(em) << 54) {}
FMT_CONSTEXPR auto operator|=(const text_style& rhs) -> text_style& { FMT_CONSTEXPR auto operator|=(text_style rhs) -> text_style& {
if (!set_foreground_color) { if (((style_ + rhs.style_) & ((1ULL << 26) | (1ULL << 53))) != 0)
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} else if (rhs.set_foreground_color) {
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
report_error("can't OR a terminal color"); report_error("can't OR a terminal color");
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color; style_ |= rhs.style_;
}
if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} else if (rhs.set_background_color) {
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
report_error("can't OR a terminal color");
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
}
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) |
static_cast<uint8_t>(rhs.ems));
return *this; return *this;
} }
friend FMT_CONSTEXPR auto operator|(text_style lhs, const text_style& rhs) friend FMT_CONSTEXPR auto operator|(text_style lhs, text_style rhs)
-> text_style { -> text_style {
return lhs |= rhs; return lhs |= rhs;
} }
FMT_CONSTEXPR auto operator==(text_style rhs) const noexcept -> bool {
return style_ == rhs.style_;
}
FMT_CONSTEXPR auto operator!=(text_style rhs) const noexcept -> bool {
return !(*this == rhs);
}
FMT_CONSTEXPR auto has_foreground() const noexcept -> bool { FMT_CONSTEXPR auto has_foreground() const noexcept -> bool {
return set_foreground_color; return (style_ & (1 << 24)) != 0;
} }
FMT_CONSTEXPR auto has_background() const noexcept -> bool { FMT_CONSTEXPR auto has_background() const noexcept -> bool {
return set_background_color; return (style_ & (1ULL << 51)) != 0;
} }
FMT_CONSTEXPR auto has_emphasis() const noexcept -> bool { FMT_CONSTEXPR auto has_emphasis() const noexcept -> bool {
return static_cast<uint8_t>(ems) != 0; return (style_ >> 54) != 0;
} }
FMT_CONSTEXPR auto get_foreground() const noexcept -> detail::color_type { FMT_CONSTEXPR auto get_foreground() const noexcept -> detail::color_type {
FMT_ASSERT(has_foreground(), "no foreground specified for this style"); FMT_ASSERT(has_foreground(), "no foreground specified for this style");
return foreground_color; return style_ & 0x3FFFFFF;
} }
FMT_CONSTEXPR auto get_background() const noexcept -> detail::color_type { FMT_CONSTEXPR auto get_background() const noexcept -> detail::color_type {
FMT_ASSERT(has_background(), "no background specified for this style"); FMT_ASSERT(has_background(), "no background specified for this style");
return background_color; return (style_ >> 27) & 0x3FFFFFF;
} }
FMT_CONSTEXPR auto get_emphasis() const noexcept -> emphasis { FMT_CONSTEXPR auto get_emphasis() const noexcept -> emphasis {
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style"); FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
return ems; return static_cast<emphasis>(style_ >> 54);
} }
private: private:
FMT_CONSTEXPR text_style(bool is_foreground, FMT_CONSTEXPR text_style(uint64_t style) noexcept : style_(style) {}
detail::color_type text_color) noexcept
: set_foreground_color(), set_background_color(), ems() {
if (is_foreground) {
foreground_color = text_color;
set_foreground_color = true;
} else {
background_color = text_color;
set_background_color = true;
}
}
friend FMT_CONSTEXPR auto fg(detail::color_type foreground) noexcept friend FMT_CONSTEXPR auto fg(detail::color_type foreground) noexcept
-> text_style; -> text_style;
@ -303,23 +341,19 @@ class text_style {
friend FMT_CONSTEXPR auto bg(detail::color_type background) noexcept friend FMT_CONSTEXPR auto bg(detail::color_type background) noexcept
-> text_style; -> text_style;
detail::color_type foreground_color; uint64_t style_ = 0;
detail::color_type background_color;
bool set_foreground_color;
bool set_background_color;
emphasis ems;
}; };
/// Creates a text style from the foreground (text) color. /// Creates a text style from the foreground (text) color.
FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept
-> text_style { -> text_style {
return text_style(true, foreground); return foreground.value_;
} }
/// Creates a text style from the background color. /// Creates a text style from the background color.
FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept
-> text_style { -> text_style {
return text_style(false, background); return static_cast<uint64_t>(background.value_) << 27;
} }
FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept
@ -334,9 +368,9 @@ template <typename Char> struct ansi_color_escape {
const char* esc) noexcept { const char* esc) noexcept {
// If we have a terminal color, we need to output another escape code // If we have a terminal color, we need to output another escape code
// sequence. // sequence.
if (!text_color.is_rgb) { if (text_color.is_terminal_color()) {
bool is_background = esc == string_view("\x1b[48;2;"); bool is_background = esc == string_view("\x1b[48;2;");
uint32_t value = text_color.value.term_color; uint32_t value = text_color.value();
// Background ASCII codes are the same as the foreground ones but with // Background ASCII codes are the same as the foreground ones but with
// 10 more. // 10 more.
if (is_background) value += 10u; if (is_background) value += 10u;
@ -360,7 +394,7 @@ template <typename Char> struct ansi_color_escape {
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
buffer[i] = static_cast<Char>(esc[i]); buffer[i] = static_cast<Char>(esc[i]);
} }
rgb color(text_color.value.rgb_color); rgb color(text_color.value());
to_esc(color.r, buffer + 7, ';'); to_esc(color.r, buffer + 7, ';');
to_esc(color.g, buffer + 11, ';'); to_esc(color.g, buffer + 11, ';');
to_esc(color.b, buffer + 15, 'm'); to_esc(color.b, buffer + 15, 'm');
@ -448,32 +482,26 @@ template <typename T> struct styled_arg : view {
}; };
template <typename Char> template <typename Char>
void vformat_to(buffer<Char>& buf, const text_style& ts, void vformat_to(buffer<Char>& buf, text_style ts, basic_string_view<Char> fmt,
basic_string_view<Char> fmt,
basic_format_args<buffered_context<Char>> args) { basic_format_args<buffered_context<Char>> args) {
bool has_style = false;
if (ts.has_emphasis()) { if (ts.has_emphasis()) {
has_style = true;
auto emphasis = make_emphasis<Char>(ts.get_emphasis()); auto emphasis = make_emphasis<Char>(ts.get_emphasis());
buf.append(emphasis.begin(), emphasis.end()); buf.append(emphasis.begin(), emphasis.end());
} }
if (ts.has_foreground()) { if (ts.has_foreground()) {
has_style = true;
auto foreground = make_foreground_color<Char>(ts.get_foreground()); auto foreground = make_foreground_color<Char>(ts.get_foreground());
buf.append(foreground.begin(), foreground.end()); buf.append(foreground.begin(), foreground.end());
} }
if (ts.has_background()) { if (ts.has_background()) {
has_style = true;
auto background = make_background_color<Char>(ts.get_background()); auto background = make_background_color<Char>(ts.get_background());
buf.append(background.begin(), background.end()); buf.append(background.begin(), background.end());
} }
vformat_to(buf, fmt, args); vformat_to(buf, fmt, args);
if (has_style) reset_color<Char>(buf); if (ts != text_style()) reset_color<Char>(buf);
} }
} // namespace detail } // namespace detail
inline void vprint(FILE* f, const text_style& ts, string_view fmt, inline void vprint(FILE* f, text_style ts, string_view fmt, format_args args) {
format_args args) {
auto buf = memory_buffer(); auto buf = memory_buffer();
detail::vformat_to(buf, ts, fmt, args); detail::vformat_to(buf, ts, fmt, args);
print(f, FMT_STRING("{}"), string_view(buf.begin(), buf.size())); print(f, FMT_STRING("{}"), string_view(buf.begin(), buf.size()));
@ -489,8 +517,7 @@ inline void vprint(FILE* f, const text_style& ts, string_view fmt,
* "Elapsed time: {0:.2f} seconds", 1.23); * "Elapsed time: {0:.2f} seconds", 1.23);
*/ */
template <typename... T> template <typename... T>
void print(FILE* f, const text_style& ts, format_string<T...> fmt, void print(FILE* f, text_style ts, format_string<T...> fmt, T&&... args) {
T&&... args) {
vprint(f, ts, fmt.str, vargs<T...>{{args...}}); vprint(f, ts, fmt.str, vargs<T...>{{args...}});
} }
@ -504,11 +531,11 @@ void print(FILE* f, const text_style& ts, format_string<T...> fmt,
* "Elapsed time: {0:.2f} seconds", 1.23); * "Elapsed time: {0:.2f} seconds", 1.23);
*/ */
template <typename... T> template <typename... T>
void print(const text_style& ts, format_string<T...> fmt, T&&... args) { void print(text_style ts, format_string<T...> fmt, T&&... args) {
return print(stdout, ts, fmt, std::forward<T>(args)...); return print(stdout, ts, fmt, std::forward<T>(args)...);
} }
inline auto vformat(const text_style& ts, string_view fmt, format_args args) inline auto vformat(text_style ts, string_view fmt, format_args args)
-> std::string { -> std::string {
auto buf = memory_buffer(); auto buf = memory_buffer();
detail::vformat_to(buf, ts, fmt, args); detail::vformat_to(buf, ts, fmt, args);
@ -528,7 +555,7 @@ inline auto vformat(const text_style& ts, string_view fmt, format_args args)
* ``` * ```
*/ */
template <typename... T> template <typename... T>
inline auto format(const text_style& ts, format_string<T...> fmt, T&&... args) inline auto format(text_style ts, format_string<T...> fmt, T&&... args)
-> std::string { -> std::string {
return fmt::vformat(ts, fmt.str, vargs<T...>{{args...}}); return fmt::vformat(ts, fmt.str, vargs<T...>{{args...}});
} }
@ -536,8 +563,8 @@ inline auto format(const text_style& ts, format_string<T...> fmt, T&&... args)
/// Formats a string with the given text_style and writes the output to `out`. /// Formats a string with the given text_style and writes the output to `out`.
template <typename OutputIt, template <typename OutputIt,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
auto vformat_to(OutputIt out, const text_style& ts, string_view fmt, auto vformat_to(OutputIt out, text_style ts, string_view fmt, format_args args)
format_args args) -> OutputIt { -> OutputIt {
auto&& buf = detail::get_buffer<char>(out); auto&& buf = detail::get_buffer<char>(out);
detail::vformat_to(buf, ts, fmt, args); detail::vformat_to(buf, ts, fmt, args);
return detail::get_iterator(buf, out); return detail::get_iterator(buf, out);
@ -555,8 +582,8 @@ auto vformat_to(OutputIt out, const text_style& ts, string_view fmt,
*/ */
template <typename OutputIt, typename... T, template <typename OutputIt, typename... T,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)> FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
inline auto format_to(OutputIt out, const text_style& ts, inline auto format_to(OutputIt out, text_style ts, format_string<T...> fmt,
format_string<T...> fmt, T&&... args) -> OutputIt { T&&... args) -> OutputIt {
return vformat_to(out, ts, fmt.str, vargs<T...>{{args...}}); return vformat_to(out, ts, fmt.str, vargs<T...>{{args...}});
} }

View File

@ -212,7 +212,7 @@ inline auto floor_log10_pow2_minus_log10_4_over_3(int e) noexcept -> int {
return (e * 631305 - 261663) >> 21; return (e * 631305 - 261663) >> 21;
} }
FMT_INLINE_VARIABLE constexpr struct { FMT_INLINE_VARIABLE constexpr struct div_small_pow10_infos_struct {
uint32_t divisor; uint32_t divisor;
int shift_amount; int shift_amount;
} div_small_pow10_infos[] = {{10, 16}, {100, 16}}; } div_small_pow10_infos[] = {{10, 16}, {100, 16}};
@ -1097,7 +1097,7 @@ template <> struct cache_accessor<double> {
return {r.high(), r.low() == 0}; return {r.high(), r.low() == 0};
} }
static auto compute_delta(cache_entry_type const& cache, int beta) noexcept static auto compute_delta(const cache_entry_type& cache, int beta) noexcept
-> uint32_t { -> uint32_t {
return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta)); return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta));
} }
@ -1526,9 +1526,8 @@ template <typename F> class glibc_file : public file_base<F> {
} }
void init_buffer() { void init_buffer() {
if (this->file_->_IO_write_ptr) return; if (this->file_->_IO_write_ptr < this->file_->_IO_write_end) return;
// Force buffer initialization by placing and removing a char in a buffer. // Force buffer initialization by placing and removing a char in a buffer.
assume(this->file_->_IO_write_ptr >= this->file_->_IO_write_end);
putc_unlocked(0, this->file_); putc_unlocked(0, this->file_);
--this->file_->_IO_write_ptr; --this->file_->_IO_write_ptr;
} }

View File

@ -117,6 +117,7 @@
# define FMT_NOINLINE # define FMT_NOINLINE
#endif #endif
// GCC 4.9 doesn't support qualified names in specializations.
namespace std { namespace std {
template <typename T> struct iterator_traits<fmt::basic_appender<T>> { template <typename T> struct iterator_traits<fmt::basic_appender<T>> {
using iterator_category = output_iterator_tag; using iterator_category = output_iterator_tag;
@ -705,7 +706,7 @@ using is_integer =
#if defined(FMT_USE_FLOAT128) #if defined(FMT_USE_FLOAT128)
// Use the provided definition. // Use the provided definition.
#elif FMT_CLANG_VERSION && FMT_HAS_INCLUDE(<quadmath.h>) #elif FMT_CLANG_VERSION >= 309 && FMT_HAS_INCLUDE(<quadmath.h>)
# define FMT_USE_FLOAT128 1 # define FMT_USE_FLOAT128 1
#elif FMT_GCC_VERSION && defined(_GLIBCXX_USE_FLOAT128) && \ #elif FMT_GCC_VERSION && defined(_GLIBCXX_USE_FLOAT128) && \
!defined(__STRICT_ANSI__) !defined(__STRICT_ANSI__)
@ -721,11 +722,10 @@ struct float128 {};
template <typename T> using is_float128 = std::is_same<T, float128>; template <typename T> using is_float128 = std::is_same<T, float128>;
template <typename T> template <typename T> struct is_floating_point : std::is_floating_point<T> {};
using is_floating_point = template <> struct is_floating_point<float128> : std::true_type {};
bool_constant<std::is_floating_point<T>::value || is_float128<T>::value>;
template <typename T, bool = std::is_floating_point<T>::value> template <typename T, bool = is_floating_point<T>::value>
struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 && struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&
sizeof(T) <= sizeof(double)> {}; sizeof(T) <= sizeof(double)> {};
template <typename T> struct is_fast_float<T, false> : std::false_type {}; template <typename T> struct is_fast_float<T, false> : std::false_type {};
@ -1613,7 +1613,7 @@ constexpr auto convert_float(T value) -> convert_float_result<T> {
} }
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, FMT_CONSTEXPR FMT_NOINLINE auto fill(OutputIt it, size_t n,
const basic_specs& specs) -> OutputIt { const basic_specs& specs) -> OutputIt {
auto fill_size = specs.fill_size(); auto fill_size = specs.fill_size();
if (fill_size == 1) return detail::fill_n(it, n, specs.fill_unit<Char>()); if (fill_size == 1) return detail::fill_n(it, n, specs.fill_unit<Char>());
@ -2472,8 +2472,8 @@ template <typename T>
struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>> struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
: std::true_type {}; : std::true_type {};
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&& template <typename T,
has_isfinite<T>::value)> FMT_ENABLE_IF(is_floating_point<T>::value&& has_isfinite<T>::value)>
FMT_CONSTEXPR20 auto isfinite(T value) -> bool { FMT_CONSTEXPR20 auto isfinite(T value) -> bool {
constexpr T inf = T(std::numeric_limits<double>::infinity()); constexpr T inf = T(std::numeric_limits<double>::infinity());
if (is_constant_evaluated()) if (is_constant_evaluated())

View File

@ -158,7 +158,8 @@ void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
FMT_EXPORT template <typename... T> FMT_EXPORT template <typename... T>
void println(std::ostream& os, format_string<T...> fmt, T&&... args) { void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
fmt::print(os, "{}\n", fmt::format(fmt, std::forward<T>(args)...)); fmt::print(os, FMT_STRING("{}\n"),
fmt::format(fmt, std::forward<T>(args)...));
} }
FMT_END_NAMESPACE FMT_END_NAMESPACE

View File

@ -774,13 +774,13 @@ struct formatter<
: formatter<detail::all<typename T::container_type>, Char> { : formatter<detail::all<typename T::container_type>, Char> {
using all = detail::all<typename T::container_type>; using all = detail::all<typename T::container_type>;
template <typename FormatContext> template <typename FormatContext>
auto format(const T& t, FormatContext& ctx) const -> decltype(ctx.out()) { auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) {
struct getter : T { struct getter : T {
static auto get(const T& t) -> all { static auto get(const T& v) -> all {
return {t.*(&getter::c)}; // Access c through the derived class. return {v.*(&getter::c)}; // Access c through the derived class.
} }
}; };
return formatter<all>::format(getter::get(t), ctx); return formatter<all>::format(getter::get(value), ctx);
} }
}; };

View File

@ -113,7 +113,6 @@ void write_escaped_path(basic_memory_buffer<Char>& quoted,
} // namespace detail } // namespace detail
FMT_EXPORT
template <typename Char> struct formatter<std::filesystem::path, Char> { template <typename Char> struct formatter<std::filesystem::path, Char> {
private: private:
format_specs specs_; format_specs specs_;
@ -182,7 +181,6 @@ FMT_END_NAMESPACE
#endif // FMT_CPP_LIB_FILESYSTEM #endif // FMT_CPP_LIB_FILESYSTEM
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <std::size_t N, typename Char> template <std::size_t N, typename Char>
struct formatter<std::bitset<N>, Char> struct formatter<std::bitset<N>, Char>
: nested_formatter<basic_string_view<Char>, Char> { : nested_formatter<basic_string_view<Char>, Char> {
@ -209,14 +207,12 @@ struct formatter<std::bitset<N>, Char>
} }
}; };
FMT_EXPORT
template <typename Char> template <typename Char>
struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {}; struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
FMT_END_NAMESPACE FMT_END_NAMESPACE
#ifdef __cpp_lib_optional #ifdef __cpp_lib_optional
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <typename T, typename Char> template <typename T, typename Char>
struct formatter<std::optional<T>, Char, struct formatter<std::optional<T>, Char,
std::enable_if_t<is_formattable<T, Char>::value>> { std::enable_if_t<is_formattable<T, Char>::value>> {
@ -279,7 +275,6 @@ FMT_END_NAMESPACE
#ifdef __cpp_lib_expected #ifdef __cpp_lib_expected
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <typename T, typename E, typename Char> template <typename T, typename E, typename Char>
struct formatter<std::expected<T, E>, Char, struct formatter<std::expected<T, E>, Char,
std::enable_if_t<(std::is_void<T>::value || std::enable_if_t<(std::is_void<T>::value ||
@ -311,7 +306,6 @@ FMT_END_NAMESPACE
#ifdef __cpp_lib_source_location #ifdef __cpp_lib_source_location
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <> struct formatter<std::source_location> { template <> struct formatter<std::source_location> {
FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); } FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }
@ -367,7 +361,6 @@ template <typename T, typename C> struct is_variant_formattable {
detail::is_variant_formattable_<T, C>::value; detail::is_variant_formattable_<T, C>::value;
}; };
FMT_EXPORT
template <typename Char> struct formatter<std::monostate, Char> { template <typename Char> struct formatter<std::monostate, Char> {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* { FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return ctx.begin(); return ctx.begin();
@ -380,7 +373,6 @@ template <typename Char> struct formatter<std::monostate, Char> {
} }
}; };
FMT_EXPORT
template <typename Variant, typename Char> template <typename Variant, typename Char>
struct formatter< struct formatter<
Variant, Char, Variant, Char,
@ -414,11 +406,11 @@ FMT_END_NAMESPACE
#endif // FMT_CPP_LIB_VARIANT #endif // FMT_CPP_LIB_VARIANT
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <> struct formatter<std::error_code> { template <> struct formatter<std::error_code> {
private: private:
format_specs specs_; format_specs specs_;
detail::arg_ref<char> width_ref_; detail::arg_ref<char> width_ref_;
bool debug_ = false;
public: public:
FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
@ -426,11 +418,19 @@ template <> struct formatter<std::error_code> {
if (it == end) return it; if (it == end) return it;
it = detail::parse_align(it, end, specs_); it = detail::parse_align(it, end, specs_);
if (it == end) return it;
char c = *it; char c = *it;
if ((c >= '0' && c <= '9') || c == '{') if (it != end && ((c >= '0' && c <= '9') || c == '{'))
it = detail::parse_width(it, end, specs_, width_ref_, ctx); it = detail::parse_width(it, end, specs_, width_ref_, ctx);
if (it != end && *it == '?') {
debug_ = true;
++it;
}
if (it != end && *it == 's') {
specs_.set_type(presentation_type::string);
++it;
}
return it; return it;
} }
@ -440,12 +440,21 @@ template <> struct formatter<std::error_code> {
auto specs = specs_; auto specs = specs_;
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
ctx); ctx);
memory_buffer buf; auto buf = memory_buffer();
if (specs_.type() == presentation_type::string) {
buf.append(ec.message());
} else {
buf.append(string_view(ec.category().name())); buf.append(string_view(ec.category().name()));
buf.push_back(':'); buf.push_back(':');
detail::write<char>(appender(buf), ec.value()); detail::write<char>(appender(buf), ec.value());
return detail::write<char>(ctx.out(), string_view(buf.data(), buf.size()), }
specs); auto quoted = memory_buffer();
auto str = string_view(buf.data(), buf.size());
if (debug_) {
detail::write_escaped_string<char>(std::back_inserter(quoted), str);
str = string_view(quoted.data(), quoted.size());
}
return detail::write<char>(ctx.out(), str, specs);
} }
}; };
@ -520,7 +529,6 @@ auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
} // namespace detail } // namespace detail
FMT_EXPORT
template <typename Char> template <typename Char>
struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types. struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
> { > {
@ -537,7 +545,6 @@ struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
}; };
#endif #endif
FMT_EXPORT
template <typename T, typename Char> template <typename T, typename Char>
struct formatter< struct formatter<
T, Char, // DEPRECATED! Mixing code unit types. T, Char, // DEPRECATED! Mixing code unit types.
@ -603,7 +610,6 @@ struct is_bit_reference_like<std::__bit_const_reference<C>> {
// We can't use std::vector<bool, Allocator>::reference and // We can't use std::vector<bool, Allocator>::reference and
// std::bitset<N>::reference because the compiler can't deduce Allocator and N // std::bitset<N>::reference because the compiler can't deduce Allocator and N
// in partial specialization. // in partial specialization.
FMT_EXPORT
template <typename BitRef, typename Char> template <typename BitRef, typename Char>
struct formatter<BitRef, Char, struct formatter<BitRef, Char,
enable_if_t<detail::is_bit_reference_like<BitRef>::value>> enable_if_t<detail::is_bit_reference_like<BitRef>::value>>
@ -623,7 +629,6 @@ template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
return p.get(); return p.get();
} }
FMT_EXPORT
template <typename T, typename Char> template <typename T, typename Char>
struct formatter<std::atomic<T>, Char, struct formatter<std::atomic<T>, Char,
enable_if_t<is_formattable<T, Char>::value>> enable_if_t<is_formattable<T, Char>::value>>
@ -636,7 +641,6 @@ struct formatter<std::atomic<T>, Char,
}; };
#ifdef __cpp_lib_atomic_flag_test #ifdef __cpp_lib_atomic_flag_test
FMT_EXPORT
template <typename Char> template <typename Char>
struct formatter<std::atomic_flag, Char> : formatter<bool, Char> { struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
template <typename FormatContext> template <typename FormatContext>
@ -647,7 +651,6 @@ struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
}; };
#endif // __cpp_lib_atomic_flag_test #endif // __cpp_lib_atomic_flag_test
FMT_EXPORT
template <typename T, typename Char> struct formatter<std::complex<T>, Char> { template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
private: private:
detail::dynamic_format_specs<Char> specs_; detail::dynamic_format_specs<Char> specs_;
@ -710,7 +713,6 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
} }
}; };
FMT_EXPORT
template <typename T, typename Char> template <typename T, typename Char>
struct formatter<std::reference_wrapper<T>, Char, struct formatter<std::reference_wrapper<T>, Char,
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>> enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>

View File

@ -112,10 +112,6 @@ inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
return {{s}}; return {{s}};
} }
template <> struct is_char<wchar_t> : std::true_type {};
template <> struct is_char<char16_t> : std::true_type {};
template <> struct is_char<char32_t> : std::true_type {};
#ifdef __cpp_char8_t #ifdef __cpp_char8_t
template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {}; template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {};
#endif #endif
@ -322,7 +318,7 @@ template <typename... T> void println(wformat_string<T...> fmt, T&&... args) {
return print(L"{}\n", fmt::format(fmt, std::forward<T>(args)...)); return print(L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
} }
inline auto vformat(const text_style& ts, wstring_view fmt, wformat_args args) inline auto vformat(text_style ts, wstring_view fmt, wformat_args args)
-> std::wstring { -> std::wstring {
auto buf = wmemory_buffer(); auto buf = wmemory_buffer();
detail::vformat_to(buf, ts, fmt, args); detail::vformat_to(buf, ts, fmt, args);
@ -330,19 +326,19 @@ inline auto vformat(const text_style& ts, wstring_view fmt, wformat_args args)
} }
template <typename... T> template <typename... T>
inline auto format(const text_style& ts, wformat_string<T...> fmt, T&&... args) inline auto format(text_style ts, wformat_string<T...> fmt, T&&... args)
-> std::wstring { -> std::wstring {
return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...)); return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));
} }
template <typename... T> template <typename... T>
FMT_DEPRECATED void print(std::FILE* f, const text_style& ts, FMT_DEPRECATED void print(std::FILE* f, text_style ts, wformat_string<T...> fmt,
wformat_string<T...> fmt, const T&... args) { const T&... args) {
vprint(f, ts, fmt, fmt::make_wformat_args(args...)); vprint(f, ts, fmt, fmt::make_wformat_args(args...));
} }
template <typename... T> template <typename... T>
FMT_DEPRECATED void print(const text_style& ts, wformat_string<T...> fmt, FMT_DEPRECATED void print(text_style ts, wformat_string<T...> fmt,
const T&... args) { const T&... args) {
return print(stdout, ts, fmt, args...); return print(stdout, ts, fmt, args...);
} }

View File

@ -1 +1 @@
7.1.2 8.1.1

View File

@ -1,3 +1,5 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library( cc_library(
name = "fmt", name = "fmt",
srcs = [ srcs = [

View File

@ -3,4 +3,5 @@ module(
compatibility_level = 10, compatibility_level = 10,
) )
bazel_dep(name = "platforms", version = "0.0.10") bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "rules_cc", version = "0.1.1")

View File

@ -13,7 +13,7 @@ The [Bazel Central Registry](https://github.com/bazelbuild/bazel-central-registr
For instance, to use {fmt} add to your `MODULE.bazel` file: For instance, to use {fmt} add to your `MODULE.bazel` file:
``` ```
bazel_dep(name = "fmt", version = "10.2.1") bazel_dep(name = "fmt", version = "11.1.4")
``` ```
### Live at head ### Live at head

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,29 @@
EXPORTS EXPORTS
DllMain
__imp_libintl_version DATA __imp_libintl_version DATA
__printf__ __printf__
_nl_expand_alias _nl_expand_alias
_nl_msg_cat_cntr DATA _nl_msg_cat_cntr DATA
bind_textdomain_codeset bind_textdomain_codeset
bindtextdomain bindtextdomain
c32isalnum
c32isalpha
c32isblank
c32iscntrl
c32isdigit
c32isgraph
c32islower
c32isprint
c32ispunct
c32isspace
c32isupper
c32isxdigit
c32tolower
c32width
dcgettext dcgettext
dcngettext dcngettext
dgettext dgettext
dngettext dngettext
getlocalename_l_unsafe
gettext gettext
libintl_asprintf libintl_asprintf
libintl_bind_textdomain_codeset libintl_bind_textdomain_codeset
@ -22,7 +36,6 @@ EXPORTS
libintl_fprintf libintl_fprintf
libintl_fwprintf libintl_fwprintf
libintl_gettext libintl_gettext
libintl_hash_string
libintl_ngettext libintl_ngettext
libintl_nl_current_default_domain DATA libintl_nl_current_default_domain DATA
libintl_nl_default_default_domain DATA libintl_nl_default_default_domain DATA
@ -46,5 +59,45 @@ EXPORTS
libintl_wbindtextdomain libintl_wbindtextdomain
libintl_wprintf libintl_wprintf
locale_charset locale_charset
mb_copy
mb_width_aux
mbiterf_next
mbrtoc32
mbsnlen
ngettext ngettext
rpl_getcwd
rpl_iswalnum
rpl_iswalpha
rpl_iswblank
rpl_iswcntrl
rpl_iswdigit
rpl_iswgraph
rpl_iswlower
rpl_iswprint
rpl_iswpunct
rpl_iswspace
rpl_iswupper
rpl_iswxdigit
rpl_localeconv
rpl_pthread_once
rpl_towlower
rpl_towupper
setlocale_messages
setlocale_messages_null
textdomain textdomain
uc_is_alnum
uc_is_alpha
uc_is_blank
uc_is_cntrl
uc_is_digit
uc_is_graph
uc_is_lower
uc_is_print
uc_is_punct
uc_is_space
uc_is_upper
uc_is_xdigit
uc_tolower
uc_width
wcwidth
wgetcwd

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -5,10 +5,25 @@ EXPORTS
_nl_msg_cat_cntr DATA _nl_msg_cat_cntr DATA
bind_textdomain_codeset bind_textdomain_codeset
bindtextdomain bindtextdomain
c32isalnum
c32isalpha
c32isblank
c32iscntrl
c32isdigit
c32isgraph
c32islower
c32isprint
c32ispunct
c32isspace
c32isupper
c32isxdigit
c32tolower
c32width
dcgettext dcgettext
dcngettext dcngettext
dgettext dgettext
dngettext dngettext
getlocalename_l_unsafe
gettext gettext
libintl_asprintf libintl_asprintf
libintl_bind_textdomain_codeset libintl_bind_textdomain_codeset
@ -21,7 +36,6 @@ EXPORTS
libintl_fprintf libintl_fprintf
libintl_fwprintf libintl_fwprintf
libintl_gettext libintl_gettext
libintl_hash_string
libintl_ngettext libintl_ngettext
libintl_nl_current_default_domain DATA libintl_nl_current_default_domain DATA
libintl_nl_default_default_domain DATA libintl_nl_default_default_domain DATA
@ -45,5 +59,45 @@ EXPORTS
libintl_wbindtextdomain libintl_wbindtextdomain
libintl_wprintf libintl_wprintf
locale_charset locale_charset
mb_copy
mb_width_aux
mbiterf_next
mbrtoc32
mbsnlen
ngettext ngettext
rpl_getcwd
rpl_iswalnum
rpl_iswalpha
rpl_iswblank
rpl_iswcntrl
rpl_iswdigit
rpl_iswgraph
rpl_iswlower
rpl_iswprint
rpl_iswpunct
rpl_iswspace
rpl_iswupper
rpl_iswxdigit
rpl_localeconv
rpl_pthread_once
rpl_towlower
rpl_towupper
setlocale_messages
setlocale_messages_null
textdomain textdomain
uc_is_alnum
uc_is_alpha
uc_is_blank
uc_is_cntrl
uc_is_digit
uc_is_graph
uc_is_lower
uc_is_print
uc_is_punct
uc_is_space
uc_is_upper
uc_is_xdigit
uc_tolower
uc_width
wcwidth
wgetcwd

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +0,0 @@
From: Michele Locati <michele@locati.it>
Date: Fri, 10 May 2019 11:11:02 +0200
Subject: [PATCH] Fix compilation of pthread_sigmask.c
--- a/gettext-tools/gnulib-tests/pthread_sigmask.c
+++ b/gettext-tools/gnulib-tests/pthread_sigmask.c
@@ -30,9 +30,9 @@
# include <unistd.h>
#endif
+#undef pthread_sigmask
int
pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask)
-#undef pthread_sigmask
{
#if HAVE_PTHREAD_SIGMASK
int ret;

View File

@ -0,0 +1,57 @@
diff '--color=auto' -ur gettext-0.24.orig/gettext-runtime/config.h.in gettext-0.24/gettext-runtime/config.h.in
--- gettext-0.24.orig/gettext-runtime/config.h.in 2025-02-25 05:25:16.000000000 -0500
+++ gettext-0.24/gettext-runtime/config.h.in 2025-04-21 13:07:02.520459899 -0400
@@ -725,10 +725,12 @@
#undef HAVE_GOOD_USELOCALE
/* Define if you have the iconv() function and it works. */
-#undef HAVE_ICONV
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV */
/* Define to 1 if you have the <iconv.h> header file. */
-#undef HAVE_ICONV_H
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV_H */
/* Define to 1 if the compiler supports one of the keywords 'inline',
'__inline__', '__inline' and effectively inlines functions marked as such.
@@ -1243,11 +1245,13 @@
#undef HAVE___INLINE
/* Define as const if the declaration of iconv() needs const. */
-#undef ICONV_CONST
+/* rom-properties: Disabled. */
+/* #undef ICONV_CONST */
/* Define to a symbolic name denoting the flavor of iconv_open()
implementation. */
-#undef ICONV_FLAVOR
+/* rom-properties: Disabled. */
+/* #undef ICONV_FLAVOR */
/* Define to the value of ${prefix}, as a string. */
#undef INSTALLPREFIX
diff '--color=auto' -ur gettext-0.24.orig/gettext-runtime/intl/config.h.in gettext-0.24/gettext-runtime/intl/config.h.in
--- gettext-0.24.orig/gettext-runtime/intl/config.h.in 2025-02-25 05:25:10.000000000 -0500
+++ gettext-0.24/gettext-runtime/intl/config.h.in 2025-04-21 13:06:27.935503569 -0400
@@ -373,7 +373,8 @@
#undef HAVE_GOOD_USELOCALE
/* Define if you have the iconv() function and it works. */
-#undef HAVE_ICONV
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV */
/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
#undef HAVE_INTMAX_T
@@ -758,7 +759,8 @@
#endif
/* Define as const if the declaration of iconv() needs const. */
-#undef ICONV_CONST
+/* rom-properties: Disabled. */
+/* #undef ICONV_CONST */
/* Define as the bit index in the word where to find bit 0 of the exponent of
'long double'. */

View File

@ -1,44 +0,0 @@
--- gettext-tools/gnulib-lib/libxml/parser.c.orig 2013-01-18 10:24:37 +0400
+++ gettext-tools/gnulib-lib/libxml/parser.c 2013-01-18 10:36:35 +0400
@@ -78,6 +78,9 @@
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
#include <libxml/xmlmemory.h>
#include <libxml/threads.h>
#include <libxml/globals.h>
@@ -97,9 +100,6 @@
#include <libxml/xmlschemastypes.h>
#include <libxml/relaxng.h>
#endif
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
--- gettext-tools/gnulib-lib/libxml/threads.c.orig 2013-01-18 10:38:24 +0400
+++ gettext-tools/gnulib-lib/libxml/threads.c 2013-01-18 10:41:11 +0400
@@ -41,15 +41,16 @@
#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#include <libxml/threads.h>
#include <libxml/globals.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

View File

@ -1,110 +0,0 @@
--- gettext-runtime/libasprintf/gnulib-lib/vasnprintf.h.orig 2023-05-19 00:19:37.000000000 -0400
+++ gettext-runtime/libasprintf/gnulib-lib/vasnprintf.h 2023-07-01 12:17:08.374266671 -0400
@@ -35,6 +35,8 @@
extern "C" {
#endif
+#if !defined(__USE_MINGW_ANSI_STDIO) && defined(__MINGW64_VERSION_MAJOR)
+
/* Write formatted output to a string dynamically allocated with malloc().
You can pass a preallocated buffer for the result in RESULTBUF and its
size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
@@ -63,6 +65,7 @@
# define asnprintf rpl_asnprintf
# define vasnprintf rpl_vasnprintf
#endif
+
extern char * asnprintf (char *restrict resultbuf, size_t *lengthp,
const char *format, ...)
_GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4));
@@ -70,6 +73,8 @@
const char *format, va_list args)
_GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0));
+#endif /* !defined(__USE_MINGW_ANSI_STDIO) && defined(__MINGW64_VERSION_MAJOR) */
+
#ifdef __cplusplus
}
#endif
--- gettext-runtime/intl/gnulib-lib/vasnprintf.h.orig 2023-05-19 00:19:37.000000000 -0400
+++ gettext-runtime/intl/gnulib-lib/vasnprintf.h 2023-07-01 12:17:08.374266671 -0400
@@ -35,6 +35,8 @@
extern "C" {
#endif
+#if !defined(__USE_MINGW_ANSI_STDIO) && defined(__MINGW64_VERSION_MAJOR)
+
/* Write formatted output to a string dynamically allocated with malloc().
You can pass a preallocated buffer for the result in RESULTBUF and its
size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
@@ -63,6 +65,7 @@
# define asnprintf rpl_asnprintf
# define vasnprintf rpl_vasnprintf
#endif
+
extern char * asnprintf (char *restrict resultbuf, size_t *lengthp,
const char *format, ...)
_GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4));
@@ -70,6 +73,8 @@
const char *format, va_list args)
_GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0));
+#endif /* !defined(__USE_MINGW_ANSI_STDIO) && defined(__MINGW64_VERSION_MAJOR) */
+
#ifdef __cplusplus
}
#endif
--- gettext-runtime/libasprintf/vasprintf.h.orig 2019-05-11 07:29:32.000000000 -0400
+++ gettext-runtime/libasprintf/vasprintf.h 2023-07-01 12:15:45.172287523 -0400
@@ -37,6 +37,8 @@
extern "C" {
#endif
+#if !defined(__USE_MINGW_ANSI_STDIO) && defined(__MINGW64_VERSION_MAJOR)
+
/* Write formatted output to a string dynamically allocated with malloc().
If the memory allocation succeeds, store the address of the string in
*RESULT and return the number of resulting bytes, excluding the trailing
@@ -46,6 +48,8 @@
extern int vasprintf (char **result, const char *format, va_list args)
__attribute__ ((__format__ (__printf__, 2, 0)));
+#endif /* !defined(__USE_MINGW_ANSI_STDIO) && defined(__MINGW64_VERSION_MAJOR) */
+
#ifdef __cplusplus
}
#endif
--- gettext-runtime/libasprintf/gnulib-lib/vasnprintf.c.orig 2023-06-12 13:34:50.000000000 -0400
+++ gettext-runtime/libasprintf/gnulib-lib/vasnprintf.c 2023-07-01 12:19:12.477235568 -0400
@@ -80,7 +80,14 @@
#endif
#include <locale.h> /* localeconv() */
+#if defined(__MINGW64_VERSION_MAJOR) && defined(__USE_MINGW_ANSI_STDIO)
+# define REMOVED__USE_MINGW_ANSI_STDIO
+# undef __USE_MINGW_ANSI_STDIO
+#endif
#include <stdio.h> /* snprintf(), sprintf() */
+#if defined(__MINGW64_VERSION_MAJOR) && defined(REMOVED__USE_MINGW_ANSI_STDIO)
+# define __USE_MINGW_ANSI_STDIO 1
+#endif
#include <stdlib.h> /* abort(), malloc(), realloc(), free() */
#include <string.h> /* memcpy(), strlen() */
#include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb() */
--- gettext-runtime/intl/gnulib-lib/vasnprintf.c.orig 2023-06-12 13:34:50.000000000 -0400
+++ gettext-runtime/intl/gnulib-lib/vasnprintf.c 2023-07-01 12:19:12.477235568 -0400
@@ -80,7 +80,14 @@
#endif
#include <locale.h> /* localeconv() */
+#if defined(__MINGW64_VERSION_MAJOR) && defined(__USE_MINGW_ANSI_STDIO)
+# define REMOVED__USE_MINGW_ANSI_STDIO
+# undef __USE_MINGW_ANSI_STDIO
+#endif
#include <stdio.h> /* snprintf(), sprintf() */
+#if defined(__MINGW64_VERSION_MAJOR) && defined(REMOVED__USE_MINGW_ANSI_STDIO)
+# define __USE_MINGW_ANSI_STDIO 1
+#endif
#include <stdlib.h> /* abort(), malloc(), realloc(), free() */
#include <string.h> /* memcpy(), strlen() */
#include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb() */

View File

@ -1,11 +0,0 @@
--- gettext-runtime/intl/libgnuintl.in.h.orig 2023-06-17 06:58:50.000000000 -0400
+++ gettext-runtime/intl/libgnuintl.in.h 2023-07-01 12:21:22.071203089 -0400
@@ -385,7 +385,7 @@
# if !((defined printf && defined _GL_STDIO_H) || defined GNULIB_overrides_printf) /* don't override gnulib */
# undef printf
-# if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__
+# if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__ || defined _MSC_VER
/* Don't break __attribute__((format(printf,M,N))).
This redefinition is only possible because the libc in NetBSD, Cygwin,
mingw does not have a function __printf__.

View File

@ -1,88 +0,0 @@
--- gettext-0.22/gettext-tools/config.h.in.orig 2023-07-28 11:27:02.945221690 -0400
+++ gettext-0.22/gettext-tools/config.h.in 2023-07-28 11:28:23.103950976 -0400
@@ -1450,10 +1450,12 @@
#undef HAVE_GOOD_USELOCALE
/* Define if you have the iconv() function and it works. */
-#undef HAVE_ICONV
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV */
/* Define to 1 if you have the <iconv.h> header file. */
-#undef HAVE_ICONV_H
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV_H */
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
@@ -2315,11 +2317,13 @@
#undef HAVE___XPG_STRERROR_R
/* Define as const if the declaration of iconv() needs const. */
-#undef ICONV_CONST
+/* rom-properties: Disabled. */
+/* #undef ICONV_CONST */
/* Define to a symbolic name denoting the flavor of iconv_open()
implementation. */
-#undef ICONV_FLAVOR
+/* rom-properties: Disabled. */
+/* #undef ICONV_FLAVOR */
/* Define to the value of ${prefix}, as a string. */
#undef INSTALLPREFIX
--- gettext-0.22/gettext-runtime/config.h.in.orig 2023-07-28 11:27:15.394179647 -0400
+++ gettext-0.22/gettext-runtime/config.h.in 2023-07-28 11:28:35.397909457 -0400
@@ -533,10 +533,12 @@
#undef HAVE_GOOD_USELOCALE
/* Define if you have the iconv() function and it works. */
-#undef HAVE_ICONV
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV */
/* Define to 1 if you have the <iconv.h> header file. */
-#undef HAVE_ICONV_H
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV_H */
/* Define to 1 if the compiler supports one of the keywords 'inline',
'__inline__', '__inline' and effectively inlines functions marked as such.
@@ -958,11 +960,13 @@
#undef HAVE___INLINE
/* Define as const if the declaration of iconv() needs const. */
-#undef ICONV_CONST
+/* rom-properties: Disabled. */
+/* #undef ICONV_CONST */
/* Define to a symbolic name denoting the flavor of iconv_open()
implementation. */
-#undef ICONV_FLAVOR
+/* rom-properties: Disabled. */
+/* #undef ICONV_FLAVOR */
/* Define to the value of ${prefix}, as a string. */
#undef INSTALLPREFIX
--- gettext-0.22/gettext-runtime/intl/config.h.in.orig 2023-06-17 07:53:52.000000000 -0400
+++ gettext-0.22/gettext-runtime/intl/config.h.in 2023-07-28 11:28:42.230886380 -0400
@@ -351,7 +351,8 @@
#undef HAVE_GOOD_USELOCALE
/* Define if you have the iconv() function and it works. */
-#undef HAVE_ICONV
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV */
/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
#undef HAVE_INTMAX_T
@@ -715,7 +716,8 @@
#endif
/* Define as const if the declaration of iconv() needs const. */
-#undef ICONV_CONST
+/* rom-properties: Disabled. */
+/* #undef ICONV_CONST */
/* Define to the value of ${prefix}, as a string. */
#undef INSTALLPREFIX

View File

@ -1,13 +0,0 @@
--- gettext-0.21/gettext-runtime/intl/dcigettext.c.orig 2020-06-06 10:03:32.000000000 -0400
+++ gettext-0.21/gettext-runtime/intl/dcigettext.c 2020-08-20 11:57:33.117783195 -0400
@@ -65,6 +65,10 @@
# include <unistd.h>
#endif
+#if defined _WIN32 && !defined __CYGWIN__
+# include <wchar.h>
+#endif
+
#include <locale.h>
#ifdef _LIBC

View File

@ -1,10 +0,0 @@
--- gettext-0.21/gettext-tools/woe32dll/gettextsrc-exports.c.orig 2019-12-23 06:21:12.000000000 -0500
+++ gettext-0.21/gettext-tools/woe32dll/gettextsrc-exports.c 2020-08-20 12:20:30.752088214 -0400
@@ -50,6 +50,7 @@
VARIABLE(formatstring_python_brace)
VARIABLE(formatstring_qt)
VARIABLE(formatstring_qt_plural)
+VARIABLE(formatstring_ruby)
VARIABLE(formatstring_scheme)
VARIABLE(formatstring_sh)
VARIABLE(formatstring_smalltalk)

View File

@ -1,17 +0,0 @@
--- gettext-0.21/gettext-runtime/config.h.in.orig 2020-07-26 17:03:57.000000000 -0400
+++ gettext-0.21/gettext-runtime/config.h.in 2020-08-20 12:49:17.066788915 -0400
@@ -391,10 +391,12 @@
#undef HAVE_GETUID
/* Define if you have the iconv() function and it works. */
-#undef HAVE_ICONV
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV */
/* Define to 1 if you have the <iconv.h> header file. */
-#undef HAVE_ICONV_H
+/* rom-properties: Disabled. */
+/* #undef HAVE_ICONV_H */
/* Define to 1 if the compiler supports one of the keywords 'inline',
'__inline__', '__inline' and effectively inlines functions marked as such.

View File

@ -1,19 +1,5 @@
From 89170435bde2d889dee8b20c74d7771e6af8f19e Mon Sep 17 00:00:00 2001 --- ./gettext-runtime/src/envsubst.c.orig 2024-12-31 05:05:32.000000000 -0500
From: Tim S <stahta01@users.sourceforge.net> +++ ./gettext-runtime/src/envsubst.c 2025-01-06 11:44:15.432757696 -0500
Date: Sun, 16 Sep 2018 10:35:04 -0400
Subject: [PATCH] Use LF as newline in envsubst
Now using underline prefix in functions as stated at:
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode
And, change mode back to prior mode
---
gettext-runtime/src/envsubst.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff a/gettext-runtime/src/envsubst.c b/gettext-runtime/src/envsubst.c
--- a/gettext-runtime/src/envsubst.c.orig 2023-06-17 06:58:50.000000000 -0400
+++ b/gettext-runtime/src/envsubst.c 2023-07-01 12:25:40.029138440 -0400
@@ -28,6 +28,11 @@ @@ -28,6 +28,11 @@
#include <unistd.h> #include <unistd.h>
#include <locale.h> #include <locale.h>
@ -23,10 +9,10 @@ diff a/gettext-runtime/src/envsubst.c b/gettext-runtime/src/envsubst.c
+# include <fcntl.h> +# include <fcntl.h>
+#endif +#endif
+ +
#include <error.h>
#include "attribute.h"
#include "noreturn.h" #include "noreturn.h"
#include "closeout.h" @@ -292,8 +297,21 @@
#include "error.h"
@@ -289,8 +294,21 @@
static void static void
print_variable (const char *var_ptr, size_t var_len) print_variable (const char *var_ptr, size_t var_len)
{ {

View File

@ -1,12 +0,0 @@
for relocate()
--- gettext-0.19.8.1/gettext-tools/gnulib-lib/Makefile.am.orig 2019-05-11 22:20:53.069987300 +0200
+++ gettext-0.19.8.1/gettext-tools/gnulib-lib/Makefile.am 2019-05-11 22:21:54.510209600 +0200
@@ -48,6 +48,8 @@
# Parametrization of the 'relocatable' module.
AM_CPPFLAGS += -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1
+AM_CPPFLAGS += -DINSTALLDIR=\"$(bindir)\"
+
# Parametrization of the 'libxml' module:
# When building a shared library, don't export the variables
# xmlMalloc, xmlMallocAtomic, xmlRealloc, xmlFree, xmlMemStrdup.

View File

@ -1,7 +1,7 @@
# Note: CMake support is community-based. The maintainers do not use CMake # Note: CMake support is community-based. The maintainers do not use CMake
# internally. # internally.
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5...3.10)
if (POLICY CMP0048) if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW) cmake_policy(SET CMP0048 NEW)

View File

@ -36,7 +36,7 @@ endif()
# as ${gmock_SOURCE_DIR} and to the root binary directory as # as ${gmock_SOURCE_DIR} and to the root binary directory as
# ${gmock_BINARY_DIR}. # ${gmock_BINARY_DIR}.
# Language "C" is required for find_package(Threads). # Language "C" is required for find_package(Threads).
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5...3.10)
cmake_policy(SET CMP0048 NEW) cmake_policy(SET CMP0048 NEW)
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)

View File

@ -46,7 +46,7 @@ endif()
# Project version: # Project version:
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5...3.10)
cmake_policy(SET CMP0048 NEW) cmake_policy(SET CMP0048 NEW)
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)

94
extlib/libpng/.cmake-format.yaml vendored Normal file
View File

@ -0,0 +1,94 @@
# https://pypi.org/project/cmakelang
# https://github.com/cheshirekow/cmake_format
# ----------------------
# Options for formatting
# ----------------------
# How wide to allow formatted cmake files
# TODO: Reflow the CMake files to allow setting the maximum line width to 100.
line_width: 255
# How many spaces to tab for indent
tab_size: 2
# If true, lines are indented using tab characters (utf-8 0x09) instead of
# <tab_size> space characters (utf-8 0x20). In cases where the layout would
# require a fractional tab character, the behavior of the fractional
# indentation is governed by <fractional_tab_policy>
use_tabchars: false
# If <use_tabchars> is True, then the value of this variable indicates how
# fractional indentions are handled during whitespace replacement. If set to
# 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set
# to `round-up` fractional indentation is replaced with a single tab character
# (utf-8 0x09) effectively shifting the column to the next tabstop
fractional_tab_policy: "use-space"
# Enable comment markup parsing and reflow
enable_markup: false
# -------------------
# Options for linting
# -------------------
# Lint codes to disable
disabled_codes: [
# TODO:
# Reconcile the CMake variable names with the patterns below, then
# re-enable the "invalid variable name XXX" messages.
"C0103",
# TODO:
# Add brief COMMENT arguments to the `add_custom_target` commands.
"C0113",
]
# Regular expression pattern describing valid function names
function_pattern: "[0-9a-z_]+"
# Regular expression pattern describing valid macro names
macro_pattern: "[0-9A-Z_]+"
# Regular expression pattern describing valid names for variables with global
# (cache) scope
global_var_pattern: "[A-Z][0-9A-Z_]+"
# Regular expression pattern describing valid names for variables with global
# scope (but internal semantic)
internal_var_pattern: "_[A-Z][0-9A-Z_]+"
# Regular expression pattern describing valid names for variables with local
# scope
local_var_pattern: "[a-z][a-z0-9_]+"
# Regular expression pattern describing valid names for privatedirectory
# variables
private_var_pattern: "_[0-9a-z_]+"
# Regular expression pattern describing valid names for public directory
# variables
public_var_pattern: "[A-Z][0-9A-Z_]+"
# Regular expression pattern describing valid names for function/macro
# arguments and loop variables.
argument_var_pattern: "[a-z][a-z0-9_]+"
# Regular expression pattern describing valid names for keywords used in
# functions or macros
keyword_pattern: "[A-Z][0-9A-Z_]+"
# In the heuristic for C0201, how many conditionals to match within a loop in
# before considering the loop a parser
max_conditionals_custom_parser: 2
# Require at least this many newlines between statements;
# require no more than this many newlines between statements;
# etc.
min_statement_spacing: 1
max_statement_spacing: 2
max_returns: 6
max_branches: 12
max_arguments: 5
max_localvars: 15
max_statements: 50

View File

@ -1,5 +1,5 @@
libpng 1.6.47 - February 18, 2025 libpng 1.6.49 - June 12, 2025
================================= =============================
This is a public release of libpng, intended for use in production code. This is a public release of libpng, intended for use in production code.
@ -9,13 +9,13 @@ Files available for download
Source files with LF line endings (for Unix/Linux): Source files with LF line endings (for Unix/Linux):
* libpng-1.6.47.tar.xz (LZMA-compressed, recommended) * libpng-1.6.49.tar.xz (LZMA-compressed, recommended)
* libpng-1.6.47.tar.gz (deflate-compressed) * libpng-1.6.49.tar.gz (deflate-compressed)
Source files with CRLF line endings (for Windows): Source files with CRLF line endings (for Windows):
* lpng1647.7z (LZMA-compressed, recommended) * lpng1649.7z (LZMA-compressed, recommended)
* lpng1647.zip (deflate-compressed) * lpng1649.zip (deflate-compressed)
Other information: Other information:
@ -25,19 +25,13 @@ Other information:
* TRADEMARK.md * TRADEMARK.md
Changes from version 1.6.46 to version 1.6.47 Changes from version 1.6.48 to version 1.6.49
--------------------------------------------- ---------------------------------------------
* Modified the behaviour of colorspace chunks in order to adhere * Added SIMD-optimized code for the RISC-V Vector Extension (RVV).
to the new precedence rules formulated in the latest draft of (Contributed by Manfred Schlaegl, Dragos Tiselice and Filip Wasil)
the PNG Specification. * Added various fixes and improvements to the build scripts and to
(Contributed by John Bowler) the sample code.
* Fixed a latent bug in `png_write_iCCP`.
This would have been a read-beyond-end-of-malloc vulnerability,
introduced early in the libpng-1.6.0 development, yet (fortunately!)
it was inaccessible before the above-mentioned modification of the
colorspace precedence rules, due to pre-existing colorspace checks.
(Reported by Bob Friesenhahn; fixed by John Bowler)
Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Send comments/corrections/commendations to png-mng-implement at lists.sf.net.

View File

@ -20,6 +20,7 @@ Authors, for copyright and licensing purposes.
* Lucas Chollet * Lucas Chollet
* Magnus Holmgren * Magnus Holmgren
* Mandar Sahastrabuddhe * Mandar Sahastrabuddhe
* Manfred Schlaegl
* Mans Rullgard * Mans Rullgard
* Matt Sarett * Matt Sarett
* Mike Klein * Mike Klein
@ -40,8 +41,9 @@ Authors, for copyright and licensing purposes.
- Zixu Wang (王子旭) - Zixu Wang (王子旭)
* Arm Holdings * Arm Holdings
- Richard Townsend - Richard Townsend
* Google Inc. * Google LLC
- Dan Field - Dan Field
- Dragoș Tiselice
- Leon Scroggins III - Leon Scroggins III
- Matt Sarett - Matt Sarett
- Mike Klein - Mike Klein
@ -51,6 +53,8 @@ Authors, for copyright and licensing purposes.
- GuXiWei (顾希伟) - GuXiWei (顾希伟)
- JinBo (金波) - JinBo (金波)
- ZhangLixia (张利霞) - ZhangLixia (张利霞)
* Samsung Group
- Filip Wasil
The build projects, the build scripts, the test scripts, and other The build projects, the build scripts, the test scripts, and other
files in the "projects", "scripts" and "tests" directories, have files in the "projects", "scripts" and "tests" directories, have

16
extlib/libpng/CHANGES vendored
View File

@ -6251,6 +6251,22 @@ Version 1.6.47 [February 18, 2025]
colorspace precedence rules, due to pre-existing colorspace checks. colorspace precedence rules, due to pre-existing colorspace checks.
(Reported by Bob Friesenhahn; fixed by John Bowler) (Reported by Bob Friesenhahn; fixed by John Bowler)
Version 1.6.48 [April 30, 2025]
Fixed the floating-point version of the mDCv setter `png_set_mDCv`.
(Reported by Mohit Bakshi; fixed by John Bowler)
Added #error directives to discourage the inclusion of private
libpng implementation header files in PNG-supporting applications.
Added the CMake build option `PNG_LIBCONF_HEADER`, to be used as an
alternative to `DFA_XTRA`.
Removed the Travis CI configuration files, with heartfelt thanks for
their generous support of our project over the past five years!
Version 1.6.49 [June 12, 2025]
Added SIMD-optimized code for the RISC-V Vector Extension (RVV).
(Contributed by Manfred Schlaegl, Dragos Tiselice and Filip Wasil)
Added various fixes and improvements to the build scripts and to
the sample code.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
Subscription is required; visit Subscription is required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement https://lists.sourceforge.net/lists/listinfo/png-mng-implement

View File

@ -1,4 +1,3 @@
# CMakeLists.txt - CMake lists for libpng # CMakeLists.txt - CMake lists for libpng
# #
# Copyright (c) 2018-2025 Cosmin Truta # Copyright (c) 2018-2025 Cosmin Truta
@ -16,13 +15,11 @@
# SPDX-License-Identifier: libpng-2.0 # SPDX-License-Identifier: libpng-2.0
# rom-properties: Disabled; use the main project policies. # rom-properties: Disabled; use the main project policies.
IF(0) #cmake_minimum_required(VERSION 3.14...4.0)
cmake_minimum_required(VERSION 3.14)
ENDIF(0) # rom-properties
set(PNGLIB_MAJOR 1) set(PNGLIB_MAJOR 1)
set(PNGLIB_MINOR 6) set(PNGLIB_MINOR 6)
set(PNGLIB_REVISION 47) set(PNGLIB_REVISION 49)
set(PNGLIB_SUBREVISION 0) set(PNGLIB_SUBREVISION 0)
#set(PNGLIB_SUBREVISION "git") #set(PNGLIB_SUBREVISION "git")
set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_REVISION}) set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_REVISION})
@ -46,19 +43,39 @@ ENDIF(0) # rom-properties
# Allow the users to specify an application-specific API prefix for libpng # Allow the users to specify an application-specific API prefix for libpng
# vendoring purposes. A standard libpng build should have no such prefix. # vendoring purposes. A standard libpng build should have no such prefix.
set(PNG_PREFIX "" set(PNG_PREFIX
""
CACHE STRING "Prefix to prepend to the API function names") CACHE STRING "Prefix to prepend to the API function names")
# Allow the users to override the postfix appended to debug library file names. # Allow the users to override the postfix appended to debug library file names.
# Previously, we used to set CMAKE_DEBUG_POSTFIX globally. That variable should # Previously, we used to set CMAKE_DEBUG_POSTFIX globally. That variable should
# not be cached, however, because doing so would affect all projects processed # not be cached, however, because doing so would affect all projects processed
# after libpng, in unexpected and undesirable ways. # after libpng, in unexpected and undesirable ways.
set(PNG_DEBUG_POSTFIX "d" set(PNG_DEBUG_POSTFIX
"d"
CACHE STRING "Postfix to append to library file names under the Debug configuration") CACHE STRING "Postfix to append to library file names under the Debug configuration")
# Allow the users to import their own extra configuration settings. # Allow the users to import their own extra configuration settings.
set(DFA_XTRA "" # Those settings can be either passed via DFA_XTRA if they are in DFA form
CACHE FILEPATH "File containing extra configuration settings") # (such as "pngusr.dfa"), or via PNG_LIBCONF_HEADER if they are in prebuilt
# header file form (such as "scripts/pnglibconf.h.prebuilt"), but not both.
# For platforms such as Android or iOS, or in certain cross-platform build
# scenarios, having a valid PNG_LIBCONF_HEADER is mandatory.
set(DFA_XTRA
""
CACHE FILEPATH "DFA file containing customized build configuration settings for libpng")
set(PNG_LIBCONF_HEADER
""
CACHE FILEPATH "C header file containing customized build configuration settings for libpng")
set(PNG_LIBCONF_HEADER_PREBUILT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt")
if(ANDROID OR IOS)
set(PNG_LIBCONF_HEADER "${PNG_LIBCONF_HEADER_PREBUILT}")
endif()
if((NOT DFA_XTRA STREQUAL "") AND (NOT PNG_LIBCONF_HEADER STREQUAL ""))
message(SEND_ERROR "The options DFA_XTRA=\"${DFA_XTRA}\" "
"and PNG_LIBCONF_HEADER=\"${PNG_LIBCONF_HEADER}\" "
"are mutually exclusive")
endif()
# rom-properties: Hard-coded values in extlib are used. # rom-properties: Hard-coded values in extlib are used.
IF(0) IF(0)
@ -67,6 +84,11 @@ option(PNG_SHARED "Build libpng as a shared library" ON)
option(PNG_STATIC "Build libpng as a static library" ON) option(PNG_STATIC "Build libpng as a static library" ON)
if(APPLE) if(APPLE)
option(PNG_FRAMEWORK "Build libpng as a framework bundle" ON) option(PNG_FRAMEWORK "Build libpng as a framework bundle" ON)
else()
option(PNG_FRAMEWORK "Build libpng as a framework bundle (not available on this platform)" OFF)
endif()
if(NOT APPLE AND PNG_FRAMEWORK)
message(SEND_ERROR "The option PNG_FRAMEWORK should not be set on this platform")
endif() endif()
# Allow the users to switch on/off the auxiliary build and test artifacts. # Allow the users to switch on/off the auxiliary build and test artifacts.
@ -88,14 +110,13 @@ option(PNG_EXECUTABLES "[Deprecated; please use PNG_TOOLS]" ON)
if(NOT PNG_EXECUTABLES) if(NOT PNG_EXECUTABLES)
message(DEPRECATION "The option PNG_EXECUTABLES has been deprecated in favour of PNG_TOOLS") message(DEPRECATION "The option PNG_EXECUTABLES has been deprecated in favour of PNG_TOOLS")
if(PNG_TOOLS) if(PNG_TOOLS)
message(AUTHOR_WARNING message(AUTHOR_WARNING "Setting PNG_TOOLS to ${PNG_EXECUTABLES}, "
"Setting PNG_TOOLS to ${PNG_EXECUTABLES}, to stay compatible with PNG_EXECUTABLES") "to stay compatible with PNG_EXECUTABLES")
set(PNG_TOOLS "${PNG_EXECUTABLES}") set(PNG_TOOLS "${PNG_EXECUTABLES}")
endif() endif()
endif() endif()
# Allow the users to configure various compilation options. # Allow the users to switch on/off the use of hardware (SIMD) optimized code.
option(PNG_DEBUG "Enable debug output" OFF)
option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON) option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON)
ENDIF(0) # rom-properties ENDIF(0) # rom-properties
@ -123,19 +144,21 @@ ENDIF(0) # rom-properties
if(PNG_BUILD_ZLIB) if(PNG_BUILD_ZLIB)
if("x${ZLIB_ROOT}" STREQUAL "x") if("x${ZLIB_ROOT}" STREQUAL "x")
#message(SEND_ERROR #message(SEND_ERROR "The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} is no longer supported; "
message(DEPRECATION # "please use ZLIB_ROOT instead")
"The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} is no longer supported; " message(DEPRECATION "The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} is no longer supported; "
"please use ZLIB_ROOT instead") "please use ZLIB_ROOT instead")
else() else()
message(SEND_ERROR #message(SEND_ERROR "The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} is no longer supported; "
"The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} is no longer supported; " # "using ZLIB_ROOT=\"${ZLIB_ROOT}\"")
message(DEPRECATION "The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} is no longer supported; "
"using ZLIB_ROOT=\"${ZLIB_ROOT}\"") "using ZLIB_ROOT=\"${ZLIB_ROOT}\"")
endif() endif()
else() else()
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
endif() endif()
# Find the math library (where available).
if(UNIX if(UNIX
AND NOT (APPLE OR BEOS OR HAIKU) AND NOT (APPLE OR BEOS OR HAIKU)
AND NOT EMSCRIPTEN) AND NOT EMSCRIPTEN)
@ -149,17 +172,26 @@ else()
# libm is not available or not needed. # libm is not available or not needed.
endif() endif()
# Silence function deprecation warnings on the Windows compilers that might
# use the MSVC Runtime library headers.
if(WIN32 AND (CMAKE_C_COMPILER_ID MATCHES "MSVC|Intel|Clang"))
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
endif()
if(PNG_HARDWARE_OPTIMIZATIONS) if(PNG_HARDWARE_OPTIMIZATIONS)
# Set definitions and sources for ARM. # Set definitions and sources for ARM.
if(PNG_TARGET_ARCHITECTURE MATCHES "^(arm|aarch)") if(PNG_TARGET_ARCHITECTURE MATCHES "^(arm|aarch)")
if(PNG_TARGET_ARCHITECTURE MATCHES "^(arm64|aarch64)") if(PNG_TARGET_ARCHITECTURE MATCHES "^(arm64|aarch64)")
set(PNG_ARM_NEON_POSSIBLE_VALUES on off) set(PNG_ARM_NEON_POSSIBLE_VALUES on off)
set(PNG_ARM_NEON "on" set(PNG_ARM_NEON
"on"
CACHE STRING "Enable ARM NEON optimizations: on|off; on is default") CACHE STRING "Enable ARM NEON optimizations: on|off; on is default")
else() else()
set(PNG_ARM_NEON_POSSIBLE_VALUES check on off) set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
set(PNG_ARM_NEON "off" set(PNG_ARM_NEON
"off"
CACHE STRING "Enable ARM NEON optimizations: check|on|off; off is default") CACHE STRING "Enable ARM NEON optimizations: check|on|off; off is default")
endif() endif()
set_property(CACHE PNG_ARM_NEON set_property(CACHE PNG_ARM_NEON
@ -185,7 +217,8 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
# Set definitions and sources for PowerPC. # Set definitions and sources for PowerPC.
if(PNG_TARGET_ARCHITECTURE MATCHES "^(powerpc|ppc64)") if(PNG_TARGET_ARCHITECTURE MATCHES "^(powerpc|ppc64)")
set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off) set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
set(PNG_POWERPC_VSX "on" set(PNG_POWERPC_VSX
"on"
CACHE STRING "Enable POWERPC VSX optimizations: on|off; on is default") CACHE STRING "Enable POWERPC VSX optimizations: on|off; on is default")
set_property(CACHE PNG_POWERPC_VSX set_property(CACHE PNG_POWERPC_VSX
PROPERTY STRINGS ${PNG_POWERPC_VSX_POSSIBLE_VALUES}) PROPERTY STRINGS ${PNG_POWERPC_VSX_POSSIBLE_VALUES})
@ -207,7 +240,8 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
# Set definitions and sources for Intel. # Set definitions and sources for Intel.
if(PNG_TARGET_ARCHITECTURE MATCHES "^(i[3-6]86|x86|amd64)") if(PNG_TARGET_ARCHITECTURE MATCHES "^(i[3-6]86|x86|amd64)")
set(PNG_INTEL_SSE_POSSIBLE_VALUES on off) set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
set(PNG_INTEL_SSE "on" set(PNG_INTEL_SSE
"on"
CACHE STRING "Enable INTEL_SSE optimizations: on|off; on is default") CACHE STRING "Enable INTEL_SSE optimizations: on|off; on is default")
set_property(CACHE PNG_INTEL_SSE set_property(CACHE PNG_INTEL_SSE
PROPERTY STRINGS ${PNG_INTEL_SSE_POSSIBLE_VALUES}) PROPERTY STRINGS ${PNG_INTEL_SSE_POSSIBLE_VALUES})
@ -258,7 +292,8 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
# Set definitions and sources for MIPS. # Set definitions and sources for MIPS.
if(PNG_TARGET_ARCHITECTURE MATCHES "^(mipsel|mips64el)") if(PNG_TARGET_ARCHITECTURE MATCHES "^(mipsel|mips64el)")
set(PNG_MIPS_MSA_POSSIBLE_VALUES on off) set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
set(PNG_MIPS_MSA "on" set(PNG_MIPS_MSA
"on"
CACHE STRING "Enable MIPS_MSA optimizations: on|off; on is default") CACHE STRING "Enable MIPS_MSA optimizations: on|off; on is default")
set_property(CACHE PNG_MIPS_MSA set_property(CACHE PNG_MIPS_MSA
PROPERTY STRINGS ${PNG_MIPS_MSA_POSSIBLE_VALUES}) PROPERTY STRINGS ${PNG_MIPS_MSA_POSSIBLE_VALUES})
@ -268,7 +303,8 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
endif() endif()
set(PNG_MIPS_MMI_POSSIBLE_VALUES on off) set(PNG_MIPS_MMI_POSSIBLE_VALUES on off)
set(PNG_MIPS_MMI "on" set(PNG_MIPS_MMI
"on"
CACHE STRING "Enable MIPS_MMI optimizations: on|off; on is default") CACHE STRING "Enable MIPS_MMI optimizations: on|off; on is default")
set_property(CACHE PNG_MIPS_MMI set_property(CACHE PNG_MIPS_MMI
PROPERTY STRINGS ${PNG_MIPS_MMI_POSSIBLE_VALUES}) PROPERTY STRINGS ${PNG_MIPS_MMI_POSSIBLE_VALUES})
@ -306,7 +342,8 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
if(PNG_TARGET_ARCHITECTURE MATCHES "^(loongarch)") if(PNG_TARGET_ARCHITECTURE MATCHES "^(loongarch)")
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
set(PNG_LOONGARCH_LSX_POSSIBLE_VALUES on off) set(PNG_LOONGARCH_LSX_POSSIBLE_VALUES on off)
set(PNG_LOONGARCH_LSX "on" set(PNG_LOONGARCH_LSX
"on"
CACHE STRING "Enable LOONGARCH_LSX optimizations: on|off; on is default") CACHE STRING "Enable LOONGARCH_LSX optimizations: on|off; on is default")
set_property(CACHE PNG_LOONGARCH_LSX set_property(CACHE PNG_LOONGARCH_LSX
PROPERTY STRINGS ${PNG_LOONGARCH_LSX_POSSIBLE_VALUES}) PROPERTY STRINGS ${PNG_LOONGARCH_LSX_POSSIBLE_VALUES})
@ -314,23 +351,51 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
if(index EQUAL -1) if(index EQUAL -1)
message(FATAL_ERROR "PNG_LOONGARCH_LSX must be one of [${PNG_LOONGARCH_LSX_POSSIBLE_VALUES}]") message(FATAL_ERROR "PNG_LOONGARCH_LSX must be one of [${PNG_LOONGARCH_LSX_POSSIBLE_VALUES}]")
elseif(NOT PNG_LOONGARCH_LSX STREQUAL "off") elseif(NOT PNG_LOONGARCH_LSX STREQUAL "off")
CHECK_C_COMPILER_FLAG("-mlsx" COMPILER_SUPPORTS_LSX) check_c_compiler_flag("-mlsx" COMPILER_SUPPORTS_LSX)
if(COMPILER_SUPPORTS_LSX) if(COMPILER_SUPPORTS_LSX)
set(libpng_loongarch_sources set(libpng_loongarch_sources
loongarch/loongarch_lsx_init.c loongarch/loongarch_lsx_init.c
loongarch/filter_lsx_intrinsics.c) loongarch/filter_lsx_intrinsics.c)
set_source_files_properties(${libpng_loongarch_sources} set_source_files_properties(${libpng_loongarch_sources}
PROPERTIES PROPERTIES COMPILE_FLAGS "-mlsx")
COMPILE_FLAGS "-mlsx")
add_definitions(-DPNG_LOONGARCH_LSX_OPT=1) add_definitions(-DPNG_LOONGARCH_LSX_OPT=1)
else() else()
message(FATAL_ERROR "Compiler does not support -mlsx option") message(FATAL_ERROR "This compiler does not support the -mlsx option")
endif() endif()
else() else()
add_definitions(-DPNG_LOONGARCH_LSX_OPT=0) add_definitions(-DPNG_LOONGARCH_LSX_OPT=0)
endif() endif()
endif() endif()
# Set definitions and sources for RISC-V.
if(PNG_TARGET_ARCHITECTURE MATCHES "^(riscv)")
include(CheckCCompilerFlag)
set(PNG_RISCV_RVV_POSSIBLE_VALUES check on off)
set(PNG_RISCV_RVV "off"
CACHE STRING "Enable RISC-V Vector optimizations: check|on|off; off is default")
set_property(CACHE PNG_RISCV_RVV
PROPERTY STRINGS ${PNG_RISCV_RVV_POSSIBLE_VALUES})
list(FIND PNG_RISCV_RVV_POSSIBLE_VALUES ${PNG_RISCV_RVV} index)
if(index EQUAL -1)
message(FATAL_ERROR "PNG_RISCV_RVV must be one of [${PNG_RISCV_RVV_POSSIBLE_VALUES}]")
elseif(NOT PNG_RISCV_RVV STREQUAL "off")
check_c_compiler_flag("-march=rv64gv1p0" COMPILER_SUPPORTS_RVV)
if(NOT COMPILER_SUPPORTS_RVV)
message(FATAL_ERROR "Compiler does not support -march=rv64gv1p0 option")
endif()
set(libpng_riscv_sources
riscv/filter_rvv_intrinsics.c
riscv/riscv_init.c)
if(PNG_RISCV_RVV STREQUAL "on")
add_definitions(-DPNG_RISCV_RVV_OPT=2)
elseif(PNG_RISCV_RVV STREQUAL "check")
add_definitions(-DPNG_RISCV_RVV_CHECK_SUPPORTED)
endif()
else()
add_definitions(-DPNG_RISCV_RVV_OPT=0)
endif()
endif()
else(PNG_HARDWARE_OPTIMIZATIONS) else(PNG_HARDWARE_OPTIMIZATIONS)
# Set definitions and sources for ARM. # Set definitions and sources for ARM.
@ -358,6 +423,11 @@ else(PNG_HARDWARE_OPTIMIZATIONS)
add_definitions(-DPNG_LOONGARCH_LSX_OPT=0) add_definitions(-DPNG_LOONGARCH_LSX_OPT=0)
endif() endif()
# Set definitions and sources for RISC-V.
if(PNG_TARGET_ARCHITECTURE MATCHES "^(riscv)")
add_definitions(-DPNG_RISCV_RVV_OPT=0)
endif()
endif(PNG_HARDWARE_OPTIMIZATIONS) endif(PNG_HARDWARE_OPTIMIZATIONS)
option(ld-version-script "Enable linker version script" ON) option(ld-version-script "Enable linker version script" ON)
@ -373,7 +443,8 @@ VERS_2 { global: sym2; main; } VERS_1;
# Solaris, because of an incompatibility with the Solaris link editor. # Solaris, because of an incompatibility with the Solaris link editor.
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS}) list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
endif() endif()
list(APPEND CMAKE_REQUIRED_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'") list(APPEND CMAKE_REQUIRED_FLAGS
"-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'")
check_c_source_compiles(" check_c_source_compiles("
void sym1(void) {} void sym1(void) {}
void sym2(void) {} void sym2(void) {}
@ -397,6 +468,9 @@ int main(void) { return 0; }
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map") file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
endif() endif()
if(PNG_LIBCONF_HEADER STREQUAL "")
# No custom configuration header file has been specified, so we build it
# from our DFA files and (optionally) out of the user-supplied DFA file.
# Find an AWK language processor. # Find an AWK language processor.
# Start with specific AWK implementations like gawk and nawk, which are # Start with specific AWK implementations like gawk and nawk, which are
# known to work with our scripts, then fall back to the system awk. # known to work with our scripts, then fall back to the system awk.
@ -406,45 +480,60 @@ if(AWK)
else() else()
message(STATUS "Could not find an AWK-compatible program") message(STATUS "Could not find an AWK-compatible program")
endif() endif()
endif()
if(NOT AWK OR (ANDROID OR IOS)) # Include the internal module PNGCheckLibconf.cmake
# No awk available to generate sources; use pre-built pnglibconf.h include("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGCheckLibconf.cmake")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h) if(NOT PNG_LIBCONF_HEADER STREQUAL "")
# Configure libpng with the user-defined pnglibconf.h file.
png_check_libconf(HEADER "${PNG_LIBCONF_HEADER}")
configure_file("${PNG_LIBCONF_HEADER}"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
@ONLY)
add_custom_target(png_genfiles)
elseif(NOT AWK)
# No AWK program available to generate pnglibconf.h.
# Configure libpng with pnglibconf.h.prebuilt.
png_check_libconf(HEADER "${PNG_LIBCONF_HEADER_PREBUILT}")
configure_file("${PNG_LIBCONF_HEADER_PREBUILT}"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
@ONLY)
add_custom_target(png_genfiles) add_custom_target(png_genfiles)
else() else()
# Include the internal module PNGGenConfig.cmake png_check_libconf(DFA_XTRA "${DFA_XTRA}")
include(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGGenConfig.cmake)
# Copy the awk scripts, converting their line endings to Unix (LF) # Include the internal module PNGGenConfig.cmake
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk include("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGGenConfig.cmake")
${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk
# Work around a limitation of various Windows AWK programs that are
# unable to process CRLF-terminated AWK scripts.
# Copy these AWK scripts to a temporary location, converting their
# line endings from Windows (CRLF) to Unix (LF) at the destination.
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk"
@ONLY @ONLY
NEWLINE_STYLE LF) NEWLINE_STYLE LF)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk "${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk"
@ONLY @ONLY
NEWLINE_STYLE LF) NEWLINE_STYLE LF)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/dfn.awk configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/dfn.awk"
${CMAKE_CURRENT_BINARY_DIR}/scripts/dfn.awk "${CMAKE_CURRENT_BINARY_DIR}/scripts/dfn.awk"
@ONLY @ONLY
NEWLINE_STYLE LF) NEWLINE_STYLE LF)
# Generate scripts/pnglibconf.h # Generate scripts/pnglibconf.h
generate_source(OUTPUT "scripts/pnglibconf.c" generate_source(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk" "${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h") "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
add_custom_target(png_scripts_pnglibconf_c
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c")
# Generate pnglibconf.c # Generate pnglibconf.c
generate_source(OUTPUT "pnglibconf.c" generate_source(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk" "${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h") "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
add_custom_target(pnglibconf_c
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c")
if(PNG_PREFIX) if(PNG_PREFIX)
set(PNGLIBCONF_H_EXTRA_DEPENDS set(PNGLIBCONF_H_EXTRA_DEPENDS
@ -455,80 +544,53 @@ else()
endif() endif()
generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
DEPENDS pnglibconf_c)
add_custom_target(pnglibconf_out
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
# Generate pnglibconf.h # Generate pnglibconf.h
generate_source(OUTPUT "pnglibconf.h" generate_source(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
${PNGLIBCONF_H_EXTRA_DEPENDS}) ${PNGLIBCONF_H_EXTRA_DEPENDS})
add_custom_target(pnglibconf_h
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c" generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h) DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
add_custom_target(png_scripts_intprefix_out
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c" generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out) "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
add_custom_target(png_scripts_prefix_out
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out")
# Generate pngprefix.h # Generate pngprefix.h
generate_source(OUTPUT "pngprefix.h" generate_source(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h"
DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS}) DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS})
add_custom_target(pngprefix_h
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c" generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h) DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
add_custom_target(png_scripts_sym_out
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c" generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt") "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt")
add_custom_target(png_scripts_symbols_out
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out")
generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c" generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
"${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h) "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
add_custom_target(png_scripts_vers_out
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
DEPENDS png_scripts_symbols_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def") "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def")
add_custom_target(png_scripts_symbols_chk
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk")
generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
DEPENDS png_scripts_sym_out)
generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
DEPENDS png_scripts_vers_out)
add_custom_target(png_genvers generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers") OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
add_custom_target(png_gensym
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
add_custom_target(png_genprebuilt add_custom_target(png_genprebuilt
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
@ -538,20 +600,20 @@ else()
# A single target handles generation of all generated files. # A single target handles generation of all generated files.
add_custom_target(png_genfiles add_custom_target(png_genfiles
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym" png_gensym DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym"
"${CMAKE_CURRENT_BINARY_DIR}/libpng.vers" png_genvers "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" pnglibconf_c "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
"${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
"${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h" pngprefix_h "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" png_scripts_intprefix_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c" png_scripts_pnglibconf_c "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" png_scripts_prefix_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" png_scripts_sym_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" png_scripts_symbols_chk "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" png_scripts_symbols_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" png_scripts_vers_out) "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
endif(NOT AWK OR (ANDROID OR IOS)) endif()
# List the source code files. # List the source code files.
set(libpng_public_hdrs set(libpng_public_hdrs
@ -565,7 +627,7 @@ set(libpng_private_hdrs
pnginfo.h pnginfo.h
pngstruct.h pngstruct.h
) )
if(AWK AND NOT (ANDROID OR IOS)) if(AWK)
list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h") list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
endif() endif()
set(libpng_sources set(libpng_sources
@ -591,7 +653,9 @@ set(libpng_sources
${libpng_mips_sources} ${libpng_mips_sources}
${libpng_powerpc_sources} ${libpng_powerpc_sources}
${libpng_loongarch_sources} ${libpng_loongarch_sources}
${libpng_riscv_sources}
) )
set(pngtest_sources set(pngtest_sources
pngtest.c pngtest.c
) )
@ -614,10 +678,13 @@ set(png_fix_itxt_sources
contrib/tools/png-fix-itxt.c contrib/tools/png-fix-itxt.c
) )
if(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID MATCHES "Clang"))) # rom-properties: FIXME: "/guard:cf" causes png_longjmp() to crash
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) # in MSVC 2022 Release builds on Windows 10.
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) IF(MSVC)
endif() FOREACH(_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS)
STRING(REPLACE "/guard:cf" "" ${_var} "${${${_var}}}")
ENDFOREACH(_var)
ENDIF(MSVC)
# rom-properties: Add -DPNG_DEBUG=0 in debug builds. # rom-properties: Add -DPNG_DEBUG=0 in debug builds.
IF(0) IF(0)
@ -663,8 +730,8 @@ if(PNG_SHARED)
add_library(png_shared SHARED ${libpng_sources}) add_library(png_shared SHARED ${libpng_sources})
add_dependencies(png_shared png_genfiles) add_dependencies(png_shared png_genfiles)
list(APPEND PNG_LIBRARY_TARGETS png_shared) list(APPEND PNG_LIBRARY_TARGETS png_shared)
set_target_properties(png_shared PROPERTIES set_target_properties(png_shared
OUTPUT_NAME "${PNG_SHARED_OUTPUT_NAME}" PROPERTIES OUTPUT_NAME "${PNG_SHARED_OUTPUT_NAME}"
DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}" DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}"
VERSION "${PNGLIB_SHARED_VERSION}" VERSION "${PNGLIB_SHARED_VERSION}"
SOVERSION "${PNGLIB_ABI_VERSION}") SOVERSION "${PNGLIB_ABI_VERSION}")
@ -675,33 +742,37 @@ if(PNG_SHARED)
if(UNIX AND AWK) if(UNIX AND AWK)
if(HAVE_LD_VERSION_SCRIPT) if(HAVE_LD_VERSION_SCRIPT)
set_target_properties(png_shared PROPERTIES set_target_properties(png_shared
LINK_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'") PROPERTIES LINK_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT) elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT)
set_target_properties(png_shared PROPERTIES set_target_properties(png_shared
LINK_FLAGS "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'") PROPERTIES LINK_FLAGS "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
endif() endif()
endif() endif()
if(APPLE) if(APPLE)
# Avoid CMake's implicit compile definition "png_shared_EXPORTS". # Avoid CMake's implicit compile definition "png_shared_EXPORTS".
set_target_properties(png_shared PROPERTIES DEFINE_SYMBOL "") set_target_properties(png_shared
PROPERTIES DEFINE_SYMBOL "")
elseif(WIN32) elseif(WIN32)
# rom-properties: Set PNG_USE_DLL to use dllimport. # rom-properties: Set PNG_USE_DLL to use dllimport.
# Use the explicit compile definition "PNG_BUILD_DLL" for Windows DLLs. # Use the explicit compile definition "PNG_BUILD_DLL" for Windows DLLs.
#set_target_properties(png_shared PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL) #set_target_properties(png_shared
# PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
target_compile_definitions(png_shared target_compile_definitions(png_shared
PRIVATE -DPNG_BUILD_DLL PRIVATE -DPNG_BUILD_DLL
INTERFACE -DPNG_USE_DLL INTERFACE -DPNG_USE_DLL
) )
endif() endif()
target_include_directories(png_shared target_include_directories(png_shared
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>) PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
target_include_directories(png_shared target_include_directories(png_shared
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>) PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
target_include_directories(png_shared SYSTEM target_include_directories(png_shared
INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>) SYSTEM
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>")
# rom-properties: ZLIB::ZLIB -> ${ZLIB_LIBRARY} # rom-properties: ZLIB::ZLIB -> ${ZLIB_LIBRARY}
target_link_libraries(png_shared PUBLIC ${ZLIB_LIBRARY} ${M_LIBRARY}) target_link_libraries(png_shared
PUBLIC ${ZLIB_LIBRARY} ${M_LIBRARY})
endif() endif()
if(PNG_STATIC) if(PNG_STATIC)
@ -713,24 +784,25 @@ if(PNG_STATIC)
add_library(png_static STATIC ${libpng_sources}) add_library(png_static STATIC ${libpng_sources})
add_dependencies(png_static png_genfiles) add_dependencies(png_static png_genfiles)
list(APPEND PNG_LIBRARY_TARGETS png_static) list(APPEND PNG_LIBRARY_TARGETS png_static)
set_target_properties(png_static PROPERTIES set_target_properties(png_static
OUTPUT_NAME "${PNG_STATIC_OUTPUT_NAME}" PROPERTIES OUTPUT_NAME "${PNG_STATIC_OUTPUT_NAME}"
DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}") DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}")
target_include_directories(png_static target_include_directories(png_static
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>) PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
target_include_directories(png_static target_include_directories(png_static
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>) PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
target_include_directories(png_static SYSTEM target_include_directories(png_static
INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>) SYSTEM
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>")
# rom-properties: ZLIB::ZLIB -> ${ZLIB_LIBRARY} # rom-properties: ZLIB::ZLIB -> ${ZLIB_LIBRARY}
target_link_libraries(png_static PUBLIC ${ZLIB_LIBRARY} ${M_LIBRARY}) target_link_libraries(png_static
PUBLIC ${ZLIB_LIBRARY} ${M_LIBRARY})
# rom-properties: Set the MSVC debug path. # rom-properties: Set the MSVC debug path.
SET_MSVC_DEBUG_PATH(png_static) SET_MSVC_DEBUG_PATH(png_static)
endif() endif()
if(PNG_FRAMEWORK AND NOT APPLE) if(PNG_FRAMEWORK AND NOT APPLE)
message(AUTHOR_WARNING message(AUTHOR_WARNING "Setting PNG_FRAMEWORK to OFF, as it only applies to Apple systems")
"Setting PNG_FRAMEWORK to OFF, as it only applies to Apple systems")
set(PNG_FRAMEWORK OFF) set(PNG_FRAMEWORK OFF)
endif() endif()
@ -738,8 +810,8 @@ if(PNG_FRAMEWORK)
add_library(png_framework SHARED ${libpng_sources}) add_library(png_framework SHARED ${libpng_sources})
add_dependencies(png_framework png_genfiles) add_dependencies(png_framework png_genfiles)
list(APPEND PNG_LIBRARY_TARGETS png_framework) list(APPEND PNG_LIBRARY_TARGETS png_framework)
set_target_properties(png_framework PROPERTIES set_target_properties(png_framework
FRAMEWORK TRUE PROPERTIES FRAMEWORK TRUE
FRAMEWORK_VERSION "${PNGLIB_VERSION}" FRAMEWORK_VERSION "${PNGLIB_VERSION}"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PNGLIB_MAJOR}.${PNGLIB_MINOR}" MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PNGLIB_MAJOR}.${PNGLIB_MINOR}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${PNGLIB_VERSION}" MACOSX_FRAMEWORK_BUNDLE_VERSION "${PNGLIB_VERSION}"
@ -749,15 +821,18 @@ if(PNG_FRAMEWORK)
OUTPUT_NAME "png" OUTPUT_NAME "png"
DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}") DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}")
# Avoid CMake's implicit compile definition "-Dpng_framework_EXPORTS". # Avoid CMake's implicit compile definition "-Dpng_framework_EXPORTS".
set_target_properties(png_framework PROPERTIES DEFINE_SYMBOL "") set_target_properties(png_framework
PROPERTIES DEFINE_SYMBOL "")
target_include_directories(png_framework target_include_directories(png_framework
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>) PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
target_include_directories(png_framework target_include_directories(png_framework
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>) PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
target_include_directories(png_framework SYSTEM target_include_directories(png_framework
INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>) SYSTEM
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>")
# rom-properties: ZLIB::ZLIB -> ${ZLIB_LIBRARY} # rom-properties: ZLIB::ZLIB -> ${ZLIB_LIBRARY}
target_link_libraries(png_framework PUBLIC ${ZLIB_LIBRARY} ${M_LIBRARY}) target_link_libraries(png_framework
PUBLIC ${ZLIB_LIBRARY} ${M_LIBRARY})
endif() endif()
if(NOT PNG_LIBRARY_TARGETS) if(NOT PNG_LIBRARY_TARGETS)
@ -770,7 +845,7 @@ if(PNG_TESTS AND PNG_SHARED)
enable_testing() enable_testing()
# Include the internal module PNGTest.cmake # Include the internal module PNGTest.cmake
include(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGTest.cmake) include("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGTest.cmake")
# Find test PNG files by globbing, but sort lists to ensure # Find test PNG files by globbing, but sort lists to ensure
# consistency between different filesystems. # consistency between different filesystems.
@ -784,7 +859,8 @@ if(PNG_TESTS AND PNG_SHARED)
set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png") set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png")
add_executable(pngtest ${pngtest_sources}) add_executable(pngtest ${pngtest_sources})
target_link_libraries(pngtest PRIVATE png_shared) target_link_libraries(pngtest
PRIVATE png_shared)
png_add_test(NAME pngtest png_add_test(NAME pngtest
COMMAND pngtest COMMAND pngtest
@ -795,7 +871,8 @@ if(PNG_TESTS AND PNG_SHARED)
FILES "${TEST_PNG3_PNGS}") FILES "${TEST_PNG3_PNGS}")
add_executable(pngvalid ${pngvalid_sources}) add_executable(pngvalid ${pngvalid_sources})
target_link_libraries(pngvalid PRIVATE png_shared) target_link_libraries(pngvalid
PRIVATE png_shared)
png_add_test(NAME pngvalid-gamma-16-to-8 png_add_test(NAME pngvalid-gamma-16-to-8
COMMAND pngvalid COMMAND pngvalid
@ -841,7 +918,8 @@ if(PNG_TESTS AND PNG_SHARED)
OPTIONS --transform) OPTIONS --transform)
add_executable(pngstest ${pngstest_sources}) add_executable(pngstest ${pngstest_sources})
target_link_libraries(pngstest PRIVATE png_shared) target_link_libraries(pngstest
PRIVATE png_shared)
foreach(gamma_type 1.8 linear none sRGB) foreach(gamma_type 1.8 linear none sRGB)
foreach(alpha_type none alpha) foreach(alpha_type none alpha)
@ -896,7 +974,8 @@ if(PNG_TESTS AND PNG_SHARED)
endforeach() endforeach()
add_executable(pngunknown ${pngunknown_sources}) add_executable(pngunknown ${pngunknown_sources})
target_link_libraries(pngunknown PRIVATE png_shared) target_link_libraries(pngunknown
PRIVATE png_shared)
png_add_test(NAME pngunknown-discard png_add_test(NAME pngunknown-discard
COMMAND pngunknown COMMAND pngunknown
@ -912,7 +991,8 @@ if(PNG_TESTS AND PNG_SHARED)
FILES "${PNGTEST_PNG}") FILES "${PNGTEST_PNG}")
png_add_test(NAME pngunknown-sAPI png_add_test(NAME pngunknown-sAPI
COMMAND pngunknown COMMAND pngunknown
OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save OPTIONS --strict
bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save
FILES "${PNGTEST_PNG}") FILES "${PNGTEST_PNG}")
png_add_test(NAME pngunknown-save png_add_test(NAME pngunknown-save
COMMAND pngunknown COMMAND pngunknown
@ -928,7 +1008,8 @@ if(PNG_TESTS AND PNG_SHARED)
FILES "${PNGTEST_PNG}") FILES "${PNGTEST_PNG}")
add_executable(pngimage ${pngimage_sources}) add_executable(pngimage ${pngimage_sources})
target_link_libraries(pngimage PRIVATE png_shared) target_link_libraries(pngimage
PRIVATE png_shared)
png_add_test(NAME pngimage-quick png_add_test(NAME pngimage-quick
COMMAND pngimage COMMAND pngimage
@ -942,11 +1023,13 @@ endif()
if(PNG_SHARED AND PNG_TOOLS) if(PNG_SHARED AND PNG_TOOLS)
add_executable(pngfix ${pngfix_sources}) add_executable(pngfix ${pngfix_sources})
target_link_libraries(pngfix PRIVATE png_shared) target_link_libraries(pngfix
PRIVATE png_shared)
set(PNG_BIN_TARGETS pngfix) set(PNG_BIN_TARGETS pngfix)
add_executable(png-fix-itxt ${png_fix_itxt_sources}) add_executable(png-fix-itxt ${png_fix_itxt_sources})
target_link_libraries(png-fix-itxt PRIVATE ZLIB::ZLIB ${M_LIBRARY}) target_link_libraries(png-fix-itxt
PRIVATE ZLIB::ZLIB ${M_LIBRARY})
list(APPEND PNG_BIN_TARGETS png-fix-itxt) list(APPEND PNG_BIN_TARGETS png-fix-itxt)
endif() endif()
@ -960,12 +1043,11 @@ function(create_symlink DEST_FILE)
# CMake version 3.13. # CMake version 3.13.
cmake_parse_arguments(_SYM "" "FILE;TARGET" "" ${ARGN}) cmake_parse_arguments(_SYM "" "FILE;TARGET" "" ${ARGN})
if(NOT _SYM_FILE AND NOT _SYM_TARGET) if(NOT _SYM_FILE AND NOT _SYM_TARGET)
message(FATAL_ERROR "create_symlink: Missing FILE or TARGET argument") message(FATAL_ERROR "create_symlink: Missing arguments: FILE or TARGET")
endif() endif()
if(_SYM_FILE AND _SYM_TARGET) if(_SYM_FILE AND _SYM_TARGET)
message(FATAL_ERROR "create_symlink: " message(FATAL_ERROR "create_symlink: Mutually-exlusive arguments:"
"The arguments FILE (${_SYM_FILE}) and TARGET (${_SYM_TARGET}) " "FILE (${_SYM_FILE}) and TARGET (${_SYM_TARGET})")
"are mutually-exclusive")
endif() endif()
if(_SYM_FILE) if(_SYM_FILE)
@ -974,12 +1056,14 @@ function(create_symlink DEST_FILE)
if(CMAKE_HOST_WIN32 AND NOT CYGWIN) if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
execute_process(COMMAND "${CMAKE_COMMAND}" execute_process(COMMAND "${CMAKE_COMMAND}"
-E copy_if_different -E copy_if_different
${_SYM_FILE} ${DEST_FILE} "${_SYM_FILE}"
"${DEST_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
else() else()
execute_process(COMMAND "${CMAKE_COMMAND}" execute_process(COMMAND "${CMAKE_COMMAND}"
-E create_symlink -E create_symlink
${_SYM_FILE} ${DEST_FILE} "${_SYM_FILE}"
"${DEST_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif() endif()
endif() endif()
@ -993,28 +1077,28 @@ function(create_symlink DEST_FILE)
POST_BUILD POST_BUILD
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
-E copy_if_different -E copy_if_different
$<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/$<TARGET_LINKER_FILE_NAME:${_SYM_TARGET}> "$<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/$<TARGET_LINKER_FILE_NAME:${_SYM_TARGET}>"
$<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/${DEST_FILE}) "$<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/${DEST_FILE}")
else() else()
add_custom_command(TARGET ${_SYM_TARGET} add_custom_command(TARGET ${_SYM_TARGET}
POST_BUILD POST_BUILD
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
-E create_symlink -E create_symlink
$<TARGET_LINKER_FILE_NAME:${_SYM_TARGET}> "$<TARGET_LINKER_FILE_NAME:${_SYM_TARGET}>"
$<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/${DEST_FILE}) "$<TARGET_LINKER_FILE_DIR:${_SYM_TARGET}>/${DEST_FILE}")
endif() endif()
endif() endif()
endfunction() endfunction()
# Create source generation scripts. # Create source generation scripts.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genchk.cmake.in configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genchk.cmake.in"
${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake"
@ONLY) @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genout.cmake.in configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genout.cmake.in"
${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake"
@ONLY) @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/gensrc.cmake.in configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/gensrc.cmake.in"
${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake"
@ONLY) @ONLY)
# libpng is a library so default to 'lib' # libpng is a library so default to 'lib'
@ -1027,17 +1111,17 @@ endif()
# Only do this on Windows for Cygwin - the files don't make much sense # Only do this on Windows for Cygwin - the files don't make much sense
# outside of a UNIX look-alike. # outside of a UNIX look-alike.
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT WIN32 OR CYGWIN OR MINGW)
set(prefix ${CMAKE_INSTALL_PREFIX}) set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix ${CMAKE_INSTALL_PREFIX}) set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
set(libdir ${CMAKE_INSTALL_FULL_LIBDIR}) set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR}) set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
set(LIBS "-lz -lm") set(LIBS "-lz -lm")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in"
${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc "${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc"
@ONLY) @ONLY)
create_symlink(libpng.pc FILE libpng${PNGLIB_ABI_VERSION}.pc) create_symlink(libpng.pc FILE libpng${PNGLIB_ABI_VERSION}.pc)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in"
${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config "${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config"
@ONLY) @ONLY)
create_symlink(libpng-config FILE libpng${PNGLIB_ABI_VERSION}-config) create_symlink(libpng-config FILE libpng${PNGLIB_ABI_VERSION}-config)
endif() endif()
@ -1053,10 +1137,10 @@ if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
# - Disabled the export rule # - Disabled the export rule
install(TARGETS ${PNG_LIBRARY_TARGETS} install(TARGETS ${PNG_LIBRARY_TARGETS}
#EXPORT libpng #EXPORT libpng
RUNTIME DESTINATION ${INSTALL_BIN_DIR} RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
#LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} #LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
#ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} #ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
FRAMEWORK DESTINATION ${INSTALL_LIB_DIR}) FRAMEWORK DESTINATION "${INSTALL_LIB_DIR}")
IF(INSTALL_DEBUG AND PNG_SHARED) IF(INSTALL_DEBUG AND PNG_SHARED)
# FIXME: Generator expression $<TARGET_PROPERTY:${_target},PDB> didn't work with CPack-3.6.1. # FIXME: Generator expression $<TARGET_PROPERTY:${_target},PDB> didn't work with CPack-3.6.1.
@ -1081,16 +1165,16 @@ if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
# Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT WIN32 OR CYGWIN OR MINGW)
create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png_shared) create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png_shared)
install(FILES $<TARGET_LINKER_FILE_DIR:png_shared>/libpng${CMAKE_SHARED_LIBRARY_SUFFIX} install(FILES "$<TARGET_LINKER_FILE_DIR:png_shared>/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}"
DESTINATION ${CMAKE_INSTALL_LIBDIR}) DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif() endif()
endif() endif()
if(PNG_STATIC) if(PNG_STATIC)
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT WIN32 OR CYGWIN OR MINGW)
create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static) create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static)
install(FILES $<TARGET_LINKER_FILE_DIR:png_static>/libpng${CMAKE_STATIC_LIBRARY_SUFFIX} install(FILES "$<TARGET_LINKER_FILE_DIR:png_static>/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}"
DESTINATION ${CMAKE_INSTALL_LIBDIR}) DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif() endif()
endif() endif()
ENDIF(0) ENDIF(0)
@ -1098,40 +1182,40 @@ endif()
if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
install(FILES ${libpng_public_hdrs} install(FILES ${libpng_public_hdrs}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES ${libpng_public_hdrs} install(FILES ${libpng_public_hdrs}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}) DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}")
endif() endif()
if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL) if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL)
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT WIN32 OR CYGWIN OR MINGW)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/libpng-config"
DESTINATION ${CMAKE_INSTALL_BINDIR}) DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config"
DESTINATION ${CMAKE_INSTALL_BINDIR}) DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif() endif()
endif() endif()
if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL) if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL)
install(TARGETS ${PNG_BIN_TARGETS} install(TARGETS ${PNG_BIN_TARGETS}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif() endif()
if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL) if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL)
# Install the man pages. # Install the man pages.
install(FILES libpng.3 libpngpf.3 install(FILES libpng.3 libpngpf.3
DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) DESTINATION "${CMAKE_INSTALL_MANDIR}/man3")
install(FILES png.5 install(FILES png.5
DESTINATION ${CMAKE_INSTALL_MANDIR}/man5) DESTINATION "${CMAKE_INSTALL_MANDIR}/man5")
# Install the pkg-config files. # Install the pkg-config files.
if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW) if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libpng.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/libpng-config"
DESTINATION ${CMAKE_INSTALL_BINDIR}) DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config"
DESTINATION ${CMAKE_INSTALL_BINDIR}) DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif() endif()
endif() endif()
@ -1140,7 +1224,7 @@ endif()
IF(0) IF(0)
if(NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL) if(NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL)
install(EXPORT libpng install(EXPORT libpng
DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpng DESTINATION "${CMAKE_INSTALL_LIBDIR}/libpng"
FILE libpng${PNGLIB_ABI_VERSION}.cmake) FILE libpng${PNGLIB_ABI_VERSION}.cmake)
endif() endif()
ENDIF(0) # rom-properties ENDIF(0) # rom-properties
@ -1149,10 +1233,10 @@ ENDIF(0) # rom-properties
if(NOT SKIP_INSTALL_CONFIG_FILE AND NOT SKIP_INSTALL_ALL) if(NOT SKIP_INSTALL_CONFIG_FILE AND NOT SKIP_INSTALL_ALL)
install(TARGETS ${PNG_LIBRARY_TARGETS} install(TARGETS ${PNG_LIBRARY_TARGETS}
EXPORT PNGTargets EXPORT PNGTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR}) FRAMEWORK DESTINATION "${CMAKE_INSTALL_LIBDIR}")
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
write_basic_package_version_file(PNGConfigVersion.cmake write_basic_package_version_file(PNGConfigVersion.cmake
@ -1162,11 +1246,11 @@ if(NOT SKIP_INSTALL_CONFIG_FILE AND NOT SKIP_INSTALL_ALL)
install(EXPORT PNGTargets install(EXPORT PNGTargets
FILE PNGTargets.cmake FILE PNGTargets.cmake
NAMESPACE PNG:: NAMESPACE PNG::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PNG) DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/PNG")
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGConfig.cmake install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/PNGConfig.cmake"
${CMAKE_CURRENT_BINARY_DIR}/PNGConfigVersion.cmake "${CMAKE_CURRENT_BINARY_DIR}/PNGConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/PNG) DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/PNG")
endif() endif()
# TODO: Create MSVC import lib for MinGW-compiled shared lib. # TODO: Create MSVC import lib for MinGW-compiled shared lib.

10
extlib/libpng/INSTALL vendored
View File

@ -136,7 +136,7 @@ Your directory structure should look like this:
depcomp, install-sh, mkinstalldirs, test-pngtest.sh, etc. depcomp, install-sh, mkinstalldirs, test-pngtest.sh, etc.
contrib contrib
arm-neon, conftest, examples, gregbook, libtests, pngminim, arm-neon, conftest, examples, gregbook, libtests, pngminim,
pngminus, pngsuite, tools, visupng pngminus, pngsuite, tools, visupng, riscv-rvv
projects projects
owatcom, visualc71, vstudio owatcom, visualc71, vstudio
scripts scripts
@ -289,6 +289,7 @@ such as one of
--enable-mips-msa=yes --enable-mips-msa=yes
--enable-intel-sse=yes --enable-intel-sse=yes
--enable-powerpc-vsx=yes --enable-powerpc-vsx=yes
--enable-riscv-rvv=yes
or enable them all at once with or enable them all at once with
@ -301,6 +302,7 @@ or more of
CPPFLAGS += "-DPNG_MIPS_MSA" CPPFLAGS += "-DPNG_MIPS_MSA"
CPPFLAGS += "-DPNG_INTEL_SSE" CPPFLAGS += "-DPNG_INTEL_SSE"
CPPFLAGS += "-DPNG_POWERPC_VSX" CPPFLAGS += "-DPNG_POWERPC_VSX"
CPPFLAGS += "-DPNG_RISCV_RVV"
See for example scripts/makefile.linux-opt See for example scripts/makefile.linux-opt
@ -317,13 +319,15 @@ to disable a particular one,
or via compiler-command options such as or via compiler-command options such as
CPPFLAGS += "-DPNG_ARM_NEON_OPT=0, -DPNG_MIPS_MSA_OPT=0, CPPFLAGS += "-DPNG_ARM_NEON_OPT=0, -DPNG_MIPS_MSA_OPT=0,
-DPNG_INTEL_SSE_OPT=0, -DPNG_POWERPC_VSX_OPT=0" -DPNG_INTEL_SSE_OPT=0, -DPNG_POWERPC_VSX_OPT=0,
-DPNG_RISCV_RVV_OPT=0"
If you are using cmake, hardware optimizations are "on" If you are using cmake, hardware optimizations are "on"
by default. To disable them, use by default. To disable them, use
cmake . -DPNG_ARM_NEON=no -DPNG_INTEL_SSE=no \ cmake . -DPNG_ARM_NEON=no -DPNG_INTEL_SSE=no \
-DPNG_MIPS_MSA=no -DPNG_POWERPC_VSX=no -DPNG_MIPS_MSA=no -DPNG_POWERPC_VSX=no \
-DPNG_RISCV_RVV=no
or disable them all at once with or disable them all at once with

View File

@ -1,4 +1,4 @@
README for libpng version 1.6.47 README for libpng version 1.6.49
================================ ================================
See the note about version numbers near the top of `png.h`. See the note about version numbers near the top of `png.h`.
@ -147,6 +147,7 @@ Files included in this distribution
loongarch/ => Optimized code for LoongArch LSX loongarch/ => Optimized code for LoongArch LSX
mips/ => Optimized code for MIPS MSA and MIPS MMI mips/ => Optimized code for MIPS MSA and MIPS MMI
powerpc/ => Optimized code for PowerPC VSX powerpc/ => Optimized code for PowerPC VSX
riscv/ => Optimized code for the RISC-V platform
ci/ => Scripts for continuous integration ci/ => Scripts for continuous integration
contrib/ => External contributions contrib/ => External contributions
arm-neon/ => Optimized code for the ARM-NEON platform arm-neon/ => Optimized code for the ARM-NEON platform
@ -162,6 +163,7 @@ Files included in this distribution
programs demonstrating the use of pngusr.dfa programs demonstrating the use of pngusr.dfa
pngminus/ => Simple pnm2png and png2pnm programs pngminus/ => Simple pnm2png and png2pnm programs
pngsuite/ => Test images pngsuite/ => Test images
riscv-rvv/ => Optimized code for the RISC-V Vector platform
testpngs/ => Test images testpngs/ => Test images
tools/ => Various tools tools/ => Various tools
visupng/ => VisualPng, a Windows viewer for PNG images visupng/ => VisualPng, a Windows viewer for PNG images

View File

@ -1,9 +1,9 @@
This copy of libpng-1.6.47 is a modified version of the original. This copy of libpng-1.6.48 is a modified version of the original.
commit 872555f4ba910252783af1507f9e7fe1653be252 commit ea127968204cc5d10f3fc9250c306b9e8cbd9b80
Release libpng version 1.6.47 Release libpng version 1.6.48
Tag: v1.6.47 Tag: v1.6.48
The following changes have been made to the original: The following changes have been made to the original:
@ -14,5 +14,5 @@ The following changes have been made to the original:
- APNG support has been added via the APNG patch: - APNG support has been added via the APNG patch:
http://sourceforge.net/projects/libpng-apng/ http://sourceforge.net/projects/libpng-apng/
To obtain the original libpng-1.6.47, visit: To obtain the original libpng-1.6.48, visit:
http://www.libpng.org/pub/png/libpng.html http://www.libpng.org/pub/png/libpng.html

View File

@ -35,14 +35,14 @@
#ifndef PNG_ARM_NEON_FILE #ifndef PNG_ARM_NEON_FILE
# if defined(__aarch64__) || defined(_M_ARM64) # if defined(__aarch64__) || defined(_M_ARM64)
/* ARM Neon is expected to be unconditionally available on ARM64. */ /* ARM Neon is expected to be unconditionally available on ARM64. */
# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64" # error PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64
# elif defined(__ARM_NEON__) || defined(__ARM_NEON) # elif defined(__ARM_NEON__) || defined(__ARM_NEON)
/* ARM Neon is expected to be available on the target CPU architecture. */ /* ARM Neon is expected to be available on the target CPU architecture. */
# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch" # error PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch
# elif defined(__linux__) # elif defined(__linux__)
# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" # define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
# else # else
# error "No support for run-time ARM Neon checking; use compile-time options" # error No support for run-time ARM Neon checking; use compile-time options
# endif # endif
#endif #endif
@ -53,7 +53,7 @@ static int png_have_neon(png_structp png_ptr);
#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ #endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
#ifndef PNG_ALIGNED_MEMORY_SUPPORTED #ifndef PNG_ALIGNED_MEMORY_SUPPORTED
# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" # error ALIGNED_MEMORY is required; please define PNG_ALIGNED_MEMORY_SUPPORTED
#endif #endif
void void

View File

@ -108,6 +108,15 @@
/* Enable POWERPC VSX optimizations */ /* Enable POWERPC VSX optimizations */
#undef PNG_POWERPC_VSX_OPT #undef PNG_POWERPC_VSX_OPT
/* Turn on RISC-V Vector optimizations at run-time */
#undef PNG_RISCV_RVV_API_SUPPORTED
/* Check for RISC-V Vector support at run-time */
#undef PNG_RISCV_RVV_CHECK_SUPPORTED
/* Enable RISCV RVV optimizations */
#undef PNG_RISCV_RVV_OPT
/* Define to 1 if all of the C89 standard headers exist (not just the ones /* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */ backward compatibility; new code need not use it. */

85
extlib/libpng/contrib/riscv-rvv/README vendored Normal file
View File

@ -0,0 +1,85 @@
OPERATING SYSTEM SPECIFIC RISC-V RVV DETECTION
----------------------------------------------
Detection of the ability to execute RISC-V Vector on a RISC-V processor
requires operating system support. (The information is not available in user
mode.)
HOW TO USE THIS
---------------
This directory contains C code fragments that can be included in
riscv/riscv_init.c by setting the macro PNG_RISCV_RVV_FILE to the file name
in "" or <> at build time. This setting is not recorded in pnglibconf.h and
can be changed simply by rebuilding riscv/riscv_init.o with the required macro
definition.
For any of this code to be used the RISC-V Vector code must be enabled and run
time checks must be supported. I.e.:
#if PNG_RISCV_RVV_OPT > 0
#ifdef PNG_RISCV_RVV_CHECK_SUPPORTED
This is done in a 'configure' build by passing configure the argument:
--enable-riscv-rvv=check
Apart from the basic Linux implementation in contrib/riscv-rvv/linux.c this
code is unsupported. That means that it is not even compiled on a regular
basis and may be broken in any given minor release.
FILE FORMAT
-----------
Each file documents its testing status as of the last time it was tested (which
may have been a long time ago):
STATUS: one of:
SUPPORTED: This indicates that the file is included in the regularly
performed test builds and bugs are fixed when discovered.
COMPILED: This indicates that the code did compile at least once. See the
more detailed description for the extent to which the result was
successful.
TESTED: This means the code was fully compiled into the libpng test programs
and these were run at least once.
BUG REPORTS: an email address to which to send reports of problems
The file is a fragment of C code. It should not define any 'extern' symbols;
everything should be static. It must define the function:
static int png_have_rvv(png_structp png_ptr);
That function must return 1 if RISC-V Vector instructions are supported, 0 if
not. It must not execute png_error unless it detects a bug. A png_error will
prevent the reading of the PNG and in the future, writing too.
BUG REPORTS
-----------
If you mail a bug report for any file that is not SUPPORTED there may only be
limited response. Consider fixing it and sending a patch to fix the problem -
this is more likely to result in action.
CONTRIBUTIONS
-------------
You may send contributions of new implementations to
png-mng-implement@sourceforge.net. Please write code in strict C90 C where
possible. Obviously OS dependencies are to be expected. If you submit code you
must have the authors permission and it must have a license that is acceptable
to the current maintainer; in particular that license must permit modification
and redistribution.
Please try to make the contribution a single file and give the file a clear and
unambiguous name that identifies the target OS. If multiple files really are
required put them all in a sub-directory.
You must also be prepared to handle bug reports from users of the code, either
by joining the png-mng-implement mailing list or by providing an email for the
"BUG REPORTS" entry or both. Please make sure that the header of the file
contains the STATUS and BUG REPORTS fields as above.
Please list the OS requirements as precisely as possible. Ideally you should
also list the environment in which the code has been tested and certainly list
any environments where you suspect it might not work.

36
extlib/libpng/contrib/riscv-rvv/linux.c vendored Normal file
View File

@ -0,0 +1,36 @@
/* contrib/riscv-rvv/linux.c
*
* Copyright (c) 2023 Google LLC
* Written by Dragoș Tiselice <dtiselice@google.com>, May 2023.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* SEE contrib/riscv-rvv/README before reporting bugs
*
* STATUS: SUPPORTED
* BUG REPORTS: png-mng-implement@sourceforge.net
*
* png_have_rvv implemented for Linux by looking for COMPAT_HWCAP_ISA_V
* via hardware capabilites API.
*
* This code is strict ANSI-C and is probably moderately portable; it does
* however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
*/
#if defined(__linux__)
#include <asm/hwcap.h>
#include <sys/auxv.h>
#endif
static int
png_have_rvv(png_structp png_ptr) {
#if defined(__linux__)
return getauxval (AT_HWCAP) & COMPAT_HWCAP_ISA_V ? 1 : 0;
#else
#pragma message( \
"warning: RISC-V Vector not supported for this platform")
return 0;
#endif
}

View File

@ -2,7 +2,7 @@
/* example.c - an example of using libpng /* example.c - an example of using libpng
* *
* Maintained 2018-2024 Cosmin Truta * Maintained 2018-2025 Cosmin Truta
* Maintained 1998-2016 Glenn Randers-Pehrson * Maintained 1998-2016 Glenn Randers-Pehrson
* Maintained 1996-1997 Andreas Dilger * Maintained 1996-1997 Andreas Dilger
* Written 1995-1996 Guy Eric Schalnat, Group 42, Inc. * Written 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -179,11 +179,11 @@ int main(int argc, const char **argv)
* components. * components.
* *
* You do not have to read directly from a file. You can read from memory or, * You do not have to read directly from a file. You can read from memory or,
* on systems that support it, from a <stdio.h> FILE*. This is controlled by * on systems that support <stdio.h>, from a FILE object. This is controlled
* the particular png_image_read_from_ function you call at the start. * by the particular png_image_begin_read_from_ function you call at the start.
* Likewise, on write, you can write to a FILE* if your system supports it. * Likewise, on write, you can write to a FILE object if your system supports
* Check the macro PNG_STDIO_SUPPORTED to see if stdio support has been * <stdio.h>. The macro PNG_STDIO_SUPPORTED indicates if stdio is available
* included in your libpng build. * and accessible from your libpng build.
* *
* If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data, you may need to write it * If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data, you may need to write it
* in the 8-bit format for display. You do this by setting the convert_to_8bit * in the 8-bit format for display. You do this by setting the convert_to_8bit

View File

@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on: Based on:
libpng version 1.6.36, December 2018, through 1.6.47 - February 2025 libpng version 1.6.36, December 2018, through 1.6.49 - June 2025
Updated and distributed by Cosmin Truta Updated and distributed by Cosmin Truta
Copyright (c) 2018-2025 Cosmin Truta Copyright (c) 2018-2025 Cosmin Truta
@ -4164,7 +4164,7 @@ be written:
int convert_to_8_bit, const void *buffer, int convert_to_8_bit, const void *buffer,
png_int_32 row_stride, const void *colormap) png_int_32 row_stride, const void *colormap)
Write the image to the given (FILE*). Write the image to the given FILE object.
With all write APIs if image is in one of the linear formats with With all write APIs if image is in one of the linear formats with
(png_uint_16) data then setting convert_to_8_bit will cause the output to be (png_uint_16) data then setting convert_to_8_bit will cause the output to be

View File

@ -1,6 +1,6 @@
.TH LIBPNG 3 "February 18, 2025" .TH LIBPNG 3 "June 12, 2025"
.SH NAME .SH NAME
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.47 libpng \- Portable Network Graphics (PNG) Reference Library 1.6.49
.SH SYNOPSIS .SH SYNOPSIS
\fB#include <png.h>\fP \fB#include <png.h>\fP
@ -528,7 +528,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on: Based on:
libpng version 1.6.36, December 2018, through 1.6.47 - February 2025 libpng version 1.6.36, December 2018, through 1.6.49 - June 2025
Updated and distributed by Cosmin Truta Updated and distributed by Cosmin Truta
Copyright (c) 2018-2025 Cosmin Truta Copyright (c) 2018-2025 Cosmin Truta
@ -4683,7 +4683,7 @@ be written:
int convert_to_8_bit, const void *buffer, int convert_to_8_bit, const void *buffer,
png_int_32 row_stride, const void *colormap) png_int_32 row_stride, const void *colormap)
Write the image to the given (FILE*). Write the image to the given FILE object.
With all write APIs if image is in one of the linear formats with With all write APIs if image is in one of the linear formats with
(png_uint_16) data then setting convert_to_8_bit will cause the output to be (png_uint_16) data then setting convert_to_8_bit will cause the output to be

Some files were not shown because too many files have changed in this diff Show More