From 2c99ac2d466fe3718189f20d2365fcde43e349f2 Mon Sep 17 00:00:00 2001 From: LeviPesin <35454228+LeviPesin@users.noreply.github.com> Date: Sat, 14 Aug 2021 20:58:13 +1000 Subject: [PATCH 0001/3088] Update libde265 version and fix Emscripten error See https://github.com/emscripten-core/emscripten/issues/10784, and, possibly, https://github.com/strukturag/libde265/commit/f38489503ee55e6b937d26a4480b081e3c4245e4 --- build-emscripten.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-emscripten.sh b/build-emscripten.sh index 663e09ed2e..81fad82516 100755 --- a/build-emscripten.sh +++ b/build-emscripten.sh @@ -5,7 +5,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" CORES=$(nproc --all) echo "Build using ${CORES} CPU cores" -LIBDE265_VERSION=1.0.2 +LIBDE265_VERSION=1.0.8 [ -s "libde265-${LIBDE265_VERSION}.tar.gz" ] || curl \ -L \ -o libde265-${LIBDE265_VERSION}.tar.gz \ From f0e38af21dbbad0b3d3017b0db892bce414d3808 Mon Sep 17 00:00:00 2001 From: mnaydenov Date: Wed, 13 Oct 2021 19:36:36 +0300 Subject: [PATCH 0002/3088] expose set_max_decoding_threads --- libheif/heif.cc | 6 ++++++ libheif/heif.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/libheif/heif.cc b/libheif/heif.cc index 0ce51531b8..793c70a85d 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -2337,3 +2337,9 @@ void heif_context_set_maximum_image_size_limit(struct heif_context* ctx, int max { ctx->context->set_maximum_image_size_limit(maximum_width); } + + +void heif_context_set_max_decoding_threads(struct heif_context* ctx, int max_threads) +{ + ctx->context->set_max_decoding_threads(max_threads); +} diff --git a/libheif/heif.h b/libheif/heif.h index fffc98d156..8f6c751c5a 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -494,6 +494,9 @@ void heif_context_debug_dump_boxes_to_file(struct heif_context* ctx, int fd); LIBHEIF_API void heif_context_set_maximum_image_size_limit(struct heif_context* ctx, int maximum_width); +LIBHEIF_API +void heif_context_set_max_decoding_threads(struct heif_context* ctx, int max_threads); + // ========================= heif_image_handle ========================= From baeb1df0e4abbda305cdd73e1ec4833eedab069a Mon Sep 17 00:00:00 2001 From: luz paz Date: Fri, 29 Oct 2021 19:43:47 -0400 Subject: [PATCH 0003/3088] Fix typo in source comment --- libheif/heif_image.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_image.cc b/libheif/heif_image.cc index 44d38e110a..1dc0659c86 100644 --- a/libheif/heif_image.cc +++ b/libheif/heif_image.cc @@ -767,7 +767,7 @@ Error HeifPixelImage::fill_RGB_16bit(uint16_t r, uint16_t g, uint16_t b, uint16_ val16 = a; break; default: - // initialization only to avoid warning of uninitalized variable. + // initialization only to avoid warning of uninitialized variable. val16 = 0; // Should already be detected by the check above ("m_planes.find"). assert(false); From 1b76c828be0f2d413acd038a2e38c34e05264359 Mon Sep 17 00:00:00 2001 From: Jamaika1 Date: Mon, 1 Nov 2021 08:52:31 +0100 Subject: [PATCH 0004/3088] Rav1e Release v0.5.0 --- third-party/rav1e.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/rav1e.cmd b/third-party/rav1e.cmd index 18fe3110d2..6ab9a91056 100644 --- a/third-party/rav1e.cmd +++ b/third-party/rav1e.cmd @@ -10,7 +10,7 @@ : # Also, the error that "The target windows-msvc is not supported yet" can safely be ignored provided that rav1e/target/release : # contains rav1e.h and rav1e.lib. -git clone -b 0.4 --depth 1 https://github.com/xiph/rav1e.git +git clone -b 0.5 --depth 1 https://github.com/xiph/rav1e.git cd rav1e cargo install cargo-c From 016435cba8b508b6f03c68d0c0d1dd1124685ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=2E=20R=C3=B8dseth?= Date: Fri, 12 Nov 2021 17:30:46 +0100 Subject: [PATCH 0005/3088] Add code for handling Exif metadata and macOS dynamic wallpaper (.heic) metadata --- go/Makefile.am | 4 +- go/heif/heif.go | 2 - go/heif/metadata.go | 216 +++++++++++++++++++++++++++++++++++++++ go/heif/metadata_test.go | 113 ++++++++++++++++++++ 4 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 go/heif/metadata.go create mode 100644 go/heif/metadata_test.go diff --git a/go/Makefile.am b/go/Makefile.am index 329261e457..7c9cfcacb4 100644 --- a/go/Makefile.am +++ b/go/Makefile.am @@ -2,7 +2,9 @@ EXTRA_DIST = \ heif/heif.go \ heif/heif_test.go \ heif/keepalive_16.go \ - heif/keepalive_17.go + heif/keepalive_17.go \ + heif/metadata.go \ + heif/metadata_test.go gopath: ln -sf ${CURDIR} ${CURDIR}/src diff --git a/go/heif/heif.go b/go/heif/heif.go index d2ee918f96..be6fc78d65 100644 --- a/go/heif/heif.go +++ b/go/heif/heif.go @@ -587,8 +587,6 @@ func (h *ImageHandle) GetThumbnail(thumbnail_id int) (*ImageHandle, error) { return &handle, convertHeifError(err) } -// TODO: EXIF metadata - // --- Image type DecodingOptions struct { diff --git a/go/heif/metadata.go b/go/heif/metadata.go new file mode 100644 index 0000000000..afb7a23ecd --- /dev/null +++ b/go/heif/metadata.go @@ -0,0 +1,216 @@ +package heif + +/* + * GO interface to libheif + * Copyright (c) 2021 Alexander F. Rødseth + * + * This file is part of heif, an example application using libheif. + * + * heif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * heif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with heif. If not, see . + */ + +/* +#cgo pkg-config: libheif +#include +#include +#include +*/ +import "C" + +import ( + "bytes" + "encoding/base64" + "errors" + "math" + "time" + "unsafe" + + "github.com/antchfx/xmlquery" + "github.com/antchfx/xpath" + "howett.net/plist" +) + +type ( + // MetadataID contains an uint that represents the ID of a block of metadata + MetadataID uint + + // TimeTable maps from image index to a time.Time that contains the hour and minute for a dynamic wallpaper image + TimeTable []time.Time +) + +var ( + errH24 = errors.New("unusual apple_desktop:h24 metadata") +) + +func (h *ImageHandle) MetadataCount() int { + n := int(C.heif_image_handle_get_number_of_metadata_blocks(h.handle, nil)) + keepAlive(h) + return n +} + +func (h *ImageHandle) MetadataIDs() []MetadataID { + nMeta := h.MetadataCount() + if nMeta == 0 { + return []MetadataID{} + } + meta := make([]C.uint, nMeta) + + C.heif_image_handle_get_list_of_metadata_block_IDs(h.handle, nil, &meta[0], C.int(nMeta)) + keepAlive(h) + metaDataIDs := make([]MetadataID, nMeta) + for i := 0; i < nMeta; i++ { + metaDataIDs[i] = MetadataID(meta[i]) + } + return metaDataIDs +} + +func (h *ImageHandle) Metadata(mID MetadataID) []byte { + nMeta := h.MetadataCount() + if nMeta == 0 { + return []byte{} + } + + nData := C.heif_image_handle_get_metadata_size(h.handle, C.uint(mID)) + keepAlive(h) + + data := C.malloc(C.sizeof_char * nData) + defer C.free(unsafe.Pointer(data)) + + C.heif_image_handle_get_metadata(h.handle, C.uint(mID), data) + keepAlive(h) + + return C.GoBytes(data, C.int(nData)) +} + +func (h *ImageHandle) ExifCount() int { + filter := C.CString("Exif") + defer C.free(unsafe.Pointer(filter)) + n := int(C.heif_image_handle_get_number_of_metadata_blocks(h.handle, filter)) + keepAlive(h) + return n +} + +func (h *ImageHandle) ExifIDs() []MetadataID { + nMeta := h.ExifCount() + if nMeta == 0 { + return []MetadataID{} + } + filter := C.CString("Exif") + defer C.free(unsafe.Pointer(filter)) + meta := make([]C.uint, nMeta) + C.heif_image_handle_get_list_of_metadata_block_IDs(h.handle, filter, &meta[0], C.int(nMeta)) + keepAlive(h) + metaDataIDs := make([]MetadataID, nMeta) + for i := 0; i < nMeta; i++ { + metaDataIDs[i] = MetadataID(meta[i]) + } + return metaDataIDs +} + +// MetadataMap takes a metadata ID and an XPath expression +// Within the metadata there may be XML, within the XML there may be a Base64 encoded string, +// and within the Base64 encoded string there may be a propery list in the Apple plist format +// and within that plist there may be a timestamp or solar position, +// encoded in the form of a property list. Oh joy. +func (h *ImageHandle) MetadataMap(mID MetadataID, xs string) (map[string]interface{}, error) { + xmlData := bytes.ReplaceAll(h.Metadata(mID), []byte{0}, []byte{}) + expr, err := xpath.Compile(xs) + if err != nil { + return nil, err + } + doc, err := xmlquery.Parse(bytes.NewReader(xmlData)) + if err != nil { + return nil, err + } + base64string, ok := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(string) + if !ok { + return nil, errors.New("could not find string at " + xs) + } + b64decoded, err := base64.StdEncoding.DecodeString(base64string) + if err != nil { + return nil, err + } + decodedMap := make(map[string]interface{}) + _, err = plist.Unmarshal(b64decoded, &decodedMap) + if err != nil { + return nil, err + } + return decodedMap, nil +} + +func (h *ImageHandle) AppleTimesMap(mID MetadataID) (map[string]interface{}, error) { + return h.MetadataMap(mID, "string(//x:xmpmeta/rdf:RDF/rdf:Description/@apple_desktop:h24)") +} + +func (h *ImageHandle) AppleSolarMap(mID MetadataID) (map[string]interface{}, error) { + return h.MetadataMap(mID, "string(//x:xmpmeta/rdf:RDF/rdf:Description/@apple_desktop:solar)") +} + +// ImageTimes returns the image times for a dynamic wallpaper. +func (h *ImageHandle) ImageTimes(mID MetadataID) (TimeTable, error) { + m, err := h.AppleTimesMap(mID) + if err != nil { + return nil, err + } + + // TODO: m["ap"] is ignored for now. It should have an "l" and "d" key but it's unclear what those might be. + // Perhaps longitude and latitude? + + tiMapList, found := m["ti"] + if !found { + return nil, err + } + tii, ok := tiMapList.([]interface{}) + if !ok { + return nil, errH24 + } + imageTimes := make(TimeTable, len(tii)) + for _, tiMap := range tii { + tiMapMap, ok := tiMap.(map[string]interface{}) + if !ok { + return nil, errH24 + } + iDuck, ok := tiMapMap["i"] + if !ok { + return nil, errH24 + } + tDuck, ok := tiMapMap["t"] + if !ok { + return nil, errH24 + } + iValue, ok := iDuck.(uint64) + if !ok { + return nil, errH24 + } + tValue, ok := tDuck.(float64) + if !ok { + return nil, errH24 + } + imageIndex := iValue + imageHourFloat := tValue * 24.0 + imageHourInt := int(math.Floor(imageHourFloat)) + imageMinuteFloat := (imageHourFloat - float64(imageHourInt)) * 60.0 + imageMinuteInt := int(math.Floor(imageMinuteFloat)) + + // Generate a time.Time that contains the correct hour and minute + now := time.Now() + timeWithHourAndMinute := time.Date(now.Year(), now.Month(), now.Day(), imageHourInt, imageMinuteInt, 0, 0, now.Location()) + + // For the found imageIndex, set the time.Time + imageTimes[imageIndex] = timeWithHourAndMinute + } + return imageTimes, nil +} + +// TODO: Also create a function that pulls out contents from the results of AppleSolarMap diff --git a/go/heif/metadata_test.go b/go/heif/metadata_test.go new file mode 100644 index 0000000000..2899919bde --- /dev/null +++ b/go/heif/metadata_test.go @@ -0,0 +1,113 @@ +package heif + +import ( + "fmt" + "path" + "testing" +) + +func TestExifCount(t *testing.T) { + ctx, err := NewContext() + if err != nil { + t.Fatalf("Can't create context: %s", err) + } + + filename := path.Join("..", "..", "examples", "mont.heic") + if err := ctx.ReadFromFile(filename); err != nil { + t.Fatalf("Can't read from %s: %s", filename, err) + } + + if count := ctx.GetNumberOfTopLevelImages(); count != 16 { + t.Errorf("Expected %d top level images, got %d", 16, count) + } + if ids := ctx.GetListOfTopLevelImageIDs(); len(ids) != 16 { + t.Errorf("Expected %d top level image ids, got %+v", 16, ids) + } + if _, err := ctx.GetPrimaryImageID(); err != nil { + t.Errorf("Expected a primary image, got %s", err) + } + handle, err := ctx.GetPrimaryImageHandle() + if err != nil { + t.Errorf("Could not get primary image handle: %s", err) + } + if !handle.IsPrimaryImage() { + t.Error("Expected primary image") + } + + exifCount := handle.ExifCount() + fmt.Println("Exif count", exifCount) + + exifIDs := handle.ExifIDs() + fmt.Println("Exif IDs", exifIDs) + + metadataCount := handle.MetadataCount() + fmt.Println("Metadata count", metadataCount) + + metadataIDs := handle.MetadataIDs() + fmt.Println("Metadata IDs", metadataIDs) + + metadataID := metadataIDs[0] + + times, err := handle.ImageTimes(metadataID) + if err != nil { + t.Fail() + } + fmt.Println(times) + + thumbnail := false + + handle.GetWidth() + handle.GetHeight() + handle.HasAlphaChannel() + handle.HasDepthImage() + count := handle.GetNumberOfDepthImages() + if ids := handle.GetListOfDepthImageIDs(); len(ids) != count { + t.Errorf("Expected %d depth image ids, got %d", count, len(ids)) + } + if !thumbnail { + count = handle.GetNumberOfThumbnails() + ids := handle.GetListOfThumbnailIDs() + if len(ids) != count { + t.Errorf("Expected %d thumbnail image ids, got %d", count, len(ids)) + } + for _, id := range ids { + if thumb, err := handle.GetThumbnail(id); err != nil { + t.Errorf("Could not get thumbnail %d: %s", id, err) + } else { + CheckHeifImage(t, thumb, true) + } + } + } + + if img, err := handle.DecodeImage(ColorspaceUndefined, ChromaUndefined, nil); err != nil { + t.Errorf("Could not decode image: %s", err) + } else { + img.GetColorspace() + img.GetChromaFormat() + } + + decodeTests := []decodeTest{ + decodeTest{ColorspaceYCbCr, Chroma420}, + decodeTest{ColorspaceYCbCr, Chroma422}, + decodeTest{ColorspaceYCbCr, Chroma444}, + decodeTest{ColorspaceRGB, Chroma444}, + decodeTest{ColorspaceRGB, ChromaInterleavedRGB}, + decodeTest{ColorspaceRGB, ChromaInterleavedRGBA}, + decodeTest{ColorspaceRGB, ChromaInterleavedRRGGBB_BE}, + decodeTest{ColorspaceRGB, ChromaInterleavedRRGGBBAA_BE}, + } + for _, test := range decodeTests { + if img, err := handle.DecodeImage(test.colorspace, test.chroma, nil); err != nil { + t.Errorf("Could not decode image with %v / %v: %s", test.colorspace, test.chroma, err) + } else { + img.GetColorspace() + img.GetChromaFormat() + + if _, err := img.GetImage(); err != nil { + t.Errorf("Could not get image with %v /%v: %s", test.colorspace, test.chroma, err) + continue + } + } + } + +} From c09696caaf1b93aa4ab02decbcaeac924fb381b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=2E=20R=C3=B8dseth?= Date: Fri, 12 Nov 2021 17:36:41 +0100 Subject: [PATCH 0006/3088] Add Go module files --- go/heif/go.mod | 15 +++++++++++++++ go/heif/go.sum | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 go/heif/go.mod create mode 100644 go/heif/go.sum diff --git a/go/heif/go.mod b/go/heif/go.mod new file mode 100644 index 0000000000..a5f79971a2 --- /dev/null +++ b/go/heif/go.mod @@ -0,0 +1,15 @@ +module github.com/strukturag/libheif/go/heif + +go 1.17 + +require ( + github.com/antchfx/xmlquery v1.3.8 + github.com/antchfx/xpath v1.2.0 + howett.net/plist v0.0.0-20201203080718-1454fab16a06 +) + +require ( + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc // indirect + golang.org/x/text v0.3.0 // indirect +) diff --git a/go/heif/go.sum b/go/heif/go.sum new file mode 100644 index 0000000000..799da5dde7 --- /dev/null +++ b/go/heif/go.sum @@ -0,0 +1,25 @@ +github.com/antchfx/xmlquery v1.3.8 h1:dRnBQM3Vk5BVJFvFwsHOLAox+mEiNw5ZusaUNCrEdoU= +github.com/antchfx/xmlquery v1.3.8/go.mod h1:wojC/BxjEkjJt6dPiAqUzoXO5nIMWtxHS8PD8TmN4ks= +github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8= +github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +howett.net/plist v0.0.0-20201203080718-1454fab16a06 h1:QDxUo/w2COstK1wIBYpzQlHX/NqaQTcf9jyz347nI58= +howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= From 633ab06a2173140665cfa742cabba466d5ea7fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=2E=20R=C3=B8dseth?= Date: Mon, 15 Nov 2021 10:50:18 +0100 Subject: [PATCH 0007/3088] Run "go fmt" --- go/heif/keepalive_16.go | 1 + go/heif/keepalive_17.go | 1 + 2 files changed, 2 insertions(+) diff --git a/go/heif/keepalive_16.go b/go/heif/keepalive_16.go index ef6941d5e4..5d416ed9dc 100644 --- a/go/heif/keepalive_16.go +++ b/go/heif/keepalive_16.go @@ -1,3 +1,4 @@ +//go:build !go1.7 // +build !go1.7 /* diff --git a/go/heif/keepalive_17.go b/go/heif/keepalive_17.go index d5b5d85a27..242cd3c051 100644 --- a/go/heif/keepalive_17.go +++ b/go/heif/keepalive_17.go @@ -1,3 +1,4 @@ +//go:build go1.7 // +build go1.7 /* From 6b0c69e5239e26fdb38493c203547fb2a2110bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=2E=20R=C3=B8dseth?= Date: Mon, 15 Nov 2021 10:50:37 +0100 Subject: [PATCH 0008/3088] Skip the metadata test if the example image is not in the repository --- go/heif/metadata_test.go | 79 ++++++++++------------------------------ 1 file changed, 19 insertions(+), 60 deletions(-) diff --git a/go/heif/metadata_test.go b/go/heif/metadata_test.go index 2899919bde..61e3a90dce 100644 --- a/go/heif/metadata_test.go +++ b/go/heif/metadata_test.go @@ -2,19 +2,34 @@ package heif import ( "fmt" + "os" "path" "testing" ) +// exists checks if the given path exists +func exists(path string) bool { + _, err := os.Stat(path) + return err == nil +} + func TestExifCount(t *testing.T) { ctx, err := NewContext() if err != nil { t.Fatalf("Can't create context: %s", err) } - filename := path.Join("..", "..", "examples", "mont.heic") - if err := ctx.ReadFromFile(filename); err != nil { - t.Fatalf("Can't read from %s: %s", filename, err) + imageFilename := path.Join("..", "..", "examples", "mont.heic") + + if !exists(imageFilename) { + // skip the test, since the image is not available in the repositry, for copyright reasons + // the test image can be downloaded from: + // https://dynamicwallpaper.club/wallpaper/la4wfuwtkg + return + } + + if err := ctx.ReadFromFile(imageFilename); err != nil { + t.Fatalf("Can't read from %s: %s", imageFilename, err) } if count := ctx.GetNumberOfTopLevelImages(); count != 16 { @@ -52,62 +67,6 @@ func TestExifCount(t *testing.T) { if err != nil { t.Fail() } - fmt.Println(times) - - thumbnail := false - - handle.GetWidth() - handle.GetHeight() - handle.HasAlphaChannel() - handle.HasDepthImage() - count := handle.GetNumberOfDepthImages() - if ids := handle.GetListOfDepthImageIDs(); len(ids) != count { - t.Errorf("Expected %d depth image ids, got %d", count, len(ids)) - } - if !thumbnail { - count = handle.GetNumberOfThumbnails() - ids := handle.GetListOfThumbnailIDs() - if len(ids) != count { - t.Errorf("Expected %d thumbnail image ids, got %d", count, len(ids)) - } - for _, id := range ids { - if thumb, err := handle.GetThumbnail(id); err != nil { - t.Errorf("Could not get thumbnail %d: %s", id, err) - } else { - CheckHeifImage(t, thumb, true) - } - } - } - - if img, err := handle.DecodeImage(ColorspaceUndefined, ChromaUndefined, nil); err != nil { - t.Errorf("Could not decode image: %s", err) - } else { - img.GetColorspace() - img.GetChromaFormat() - } - - decodeTests := []decodeTest{ - decodeTest{ColorspaceYCbCr, Chroma420}, - decodeTest{ColorspaceYCbCr, Chroma422}, - decodeTest{ColorspaceYCbCr, Chroma444}, - decodeTest{ColorspaceRGB, Chroma444}, - decodeTest{ColorspaceRGB, ChromaInterleavedRGB}, - decodeTest{ColorspaceRGB, ChromaInterleavedRGBA}, - decodeTest{ColorspaceRGB, ChromaInterleavedRRGGBB_BE}, - decodeTest{ColorspaceRGB, ChromaInterleavedRRGGBBAA_BE}, - } - for _, test := range decodeTests { - if img, err := handle.DecodeImage(test.colorspace, test.chroma, nil); err != nil { - t.Errorf("Could not decode image with %v / %v: %s", test.colorspace, test.chroma, err) - } else { - img.GetColorspace() - img.GetChromaFormat() - - if _, err := img.GetImage(); err != nil { - t.Errorf("Could not get image with %v /%v: %s", test.colorspace, test.chroma, err) - continue - } - } - } + fmt.Println(times) } From 033011ecf39bcb5023dec82d0409594389ee8943 Mon Sep 17 00:00:00 2001 From: David Korczynski Date: Tue, 30 Nov 2021 23:27:50 +0000 Subject: [PATCH 0009/3088] CI: Add CIFuzz integration --- .github/workflows/cifuzz.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/cifuzz.yml diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 0000000000..05afe801d2 --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,24 @@ +name: CIFuzz +on: [pull_request] +jobs: + Fuzzing: + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'libheif' + dry-run: false + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'libheif' + fuzz-seconds: 600 + dry-run: false + - name: Upload Crash + uses: actions/upload-artifact@v1 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts From c156662895636b5065720268aaba6ed8a0f11fff Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Fri, 3 Dec 2021 10:05:53 +0100 Subject: [PATCH 0010/3088] CI: use Ubuntu 20.04 for the mingw build to get a newer toolchain Needed a workaround for installing wine32 due to the GHA image being broken (could also be worked around by using a docker image). Might help #569 --- .github/workflows/mingw.yml | 2 +- scripts/install-ci-linux.sh | 2 ++ scripts/run-ci.sh | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 967d32722d..0b75b4cb81 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -14,7 +14,7 @@ jobs: - { MINGW: 32 } - { MINGW: 64 } env: ${{ matrix.env }} - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 diff --git a/scripts/install-ci-linux.sh b/scripts/install-ci-linux.sh index 7a05065bfa..cb2aff116d 100755 --- a/scripts/install-ci-linux.sh +++ b/scripts/install-ci-linux.sh @@ -110,6 +110,8 @@ fi if [ "$MINGW" == "32" ]; then sudo dpkg --add-architecture i386 + # https://github.com/actions/virtual-environments/issues/4589 + sudo apt install -y --allow-downgrades libpcre2-8-0=10.34-7 INSTALL_PACKAGES="$INSTALL_PACKAGES \ binutils-mingw-w64-i686 \ g++-mingw-w64-i686 \ diff --git a/scripts/run-ci.sh b/scripts/run-ci.sh index 70a55bf014..0575aadc58 100755 --- a/scripts/run-ci.sh +++ b/scripts/run-ci.sh @@ -71,14 +71,14 @@ if [ "$MINGW" == "32" ]; then unset CXX BIN_SUFFIX=.exe BIN_WRAPPER=wine - export WINEPATH="/usr/lib/gcc/i686-w64-mingw32/7.3-posix/;/usr/i686-w64-mingw32/lib" + export WINEPATH="/usr/lib/gcc/i686-w64-mingw32/9.3-posix/;/usr/i686-w64-mingw32/lib" elif [ "$MINGW" == "64" ]; then # Make sure the correct compiler will be used. unset CC unset CXX BIN_SUFFIX=.exe BIN_WRAPPER=wine64 - export WINEPATH="/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/;/usr/x86_64-w64-mingw32/lib" + export WINEPATH="/usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/;/usr/x86_64-w64-mingw32/lib" elif [ ! -z "$FUZZER" ]; then export CC="$BUILD_ROOT/clang/bin/clang" export CXX="$BUILD_ROOT/clang/bin/clang++" From 6e5b6fba9f09299ca7d8c397da121dacbcc7bc52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Dec 2021 13:21:00 +0000 Subject: [PATCH 0011/3088] Bump actions/upload-artifact from 1 to 2.3.0 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 1 to 2.3.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v1...v2.3.0) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/cifuzz.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 05afe801d2..921f12c9ca 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -17,7 +17,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2.3.0 if: failure() && steps.build.outcome == 'success' with: name: artifacts From 499a0a31d79936042c7abeef2513bb0b56b81489 Mon Sep 17 00:00:00 2001 From: Alexander Karpinsky Date: Sun, 17 Oct 2021 13:57:05 +0300 Subject: [PATCH 0012/3088] Avoid lroundf using --- libheif/heif_colorconversion.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc index f85bcccbe0..f3b254a6f9 100644 --- a/libheif/heif_colorconversion.cc +++ b/libheif/heif_colorconversion.cc @@ -306,7 +306,7 @@ static inline uint8_t clip_int_u8(int x) static inline uint16_t clip_f_u16(float fx, int32_t maxi) { - long x = lroundf(fx); + long x = (long int) (fx + 0.5f); if (x < 0) return 0; if (x > maxi) return (uint16_t) maxi; return static_cast(x); @@ -1961,7 +1961,7 @@ Op_RGB24_32_to_YCbCr::state_after_conversion(ColorState input_state, static inline uint8_t clip_f_u8(float fx) { - long x = lroundf(fx); + long x = (long int) (fx + 0.5f); if (x < 0) return 0; if (x > 255) return 255; return static_cast(x); From 6c57ba3344bf37abe55f5083825d14bc56f0fec5 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Tue, 14 Dec 2021 11:09:47 +0100 Subject: [PATCH 0013/3088] CI: Use release build for cmake. This better matches what the autoconf / automake environment uses. --- scripts/run-ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run-ci.sh b/scripts/run-ci.sh index 70a55bf014..11ee025ef7 100755 --- a/scripts/run-ci.sh +++ b/scripts/run-ci.sh @@ -124,7 +124,7 @@ fi if [ ! -z "$CMAKE" ]; then echo "Preparing cmake build files ..." - CMAKE_OPTIONS= + CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release" if [ "$CURRENT_OS" = "osx" ] ; then # Make sure the homebrew installed libraries are used when building instead # of the libraries provided by Apple. From 82070385eca01f64c587e02c0a75d60386d308c3 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 14 May 2021 09:11:25 +0200 Subject: [PATCH 0014/3088] Fix undefined behaviour from left shift. Found by Coverity Scan. --- libheif/heif_avif.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_avif.cc b/libheif/heif_avif.cc index bd233b3728..47e858a955 100644 --- a/libheif/heif_avif.cc +++ b/libheif/heif_avif.cc @@ -87,7 +87,7 @@ static uint64_t leb128(BitReader& reader) { uint64_t val = 0; for (int i = 0; i < 8; i++) { - int v = reader.get_bits(8); + int64_t v = reader.get_bits(8); val |= (v & 0x7F) << (i * 7); if (!(v & 0x80)) { break; From 67410c3ce2c8a210d42d02c790c3ac1f9791605a Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 14 May 2021 09:14:12 +0200 Subject: [PATCH 0015/3088] Calculate with 64bit to avoid potential overflow. Found by Coverity Scan. --- libheif/bitstream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/bitstream.h b/libheif/bitstream.h index b694cf4d2d..48c4c5a89c 100644 --- a/libheif/bitstream.h +++ b/libheif/bitstream.h @@ -272,7 +272,7 @@ namespace heif { int64_t get_bits_remaining() const { - return bytes_remaining*8 + nextbits_cnt; + return ((int64_t) bytes_remaining) * 8 + nextbits_cnt; } private: From 2611d39704bdb6bb37429e39660d9dedbdfff35a Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 14 May 2021 09:32:50 +0200 Subject: [PATCH 0016/3088] Assume encoded image has source size if no SPS is returned from encoder. Found by Coverity Scan. --- libheif/heif_context.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index d536c0f9c0..871d78244e 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -1966,7 +1966,8 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, err.message); } - int encoded_width, encoded_height; + int encoded_width = image->get_width(heif_channel_Y); + int encoded_height = image->get_height(heif_channel_Y); for (;;) { uint8_t* data; From 5a20339c29831cd2f72903a1ca2ff88e458dc1c2 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 14 May 2021 09:35:32 +0200 Subject: [PATCH 0017/3088] Check result of "read" call (available data was already checked above). Found by Coverity Scan. --- libheif/box.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libheif/box.cc b/libheif/box.cc index ce5362a521..2595838551 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -240,7 +240,9 @@ heif::Error heif::BoxHeader::parse(BitstreamRange& range) if (range.prepare_read(16)) { m_uuid_type.resize(16); - range.get_istream()->read((char*) m_uuid_type.data(), 16); + bool success = range.get_istream()->read((char*) m_uuid_type.data(), 16); + assert(success); + (void) success; } m_header_size += 16; @@ -2666,7 +2668,9 @@ Error Box_hvcC::parse(BitstreamRange& range) if (range.prepare_read(size)) { nal_unit.resize(size); - range.get_istream()->read((char*) nal_unit.data(), size); + bool success = range.get_istream()->read((char*) nal_unit.data(), size); + assert(success); + (void) success; } array.m_nal_units.push_back(std::move(nal_unit)); From e0ff93296f7a11c53dd028374f56ec8f0c306cc9 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 14 May 2021 09:36:34 +0200 Subject: [PATCH 0018/3088] Use result of "heif_image_handle_is_primary_image". Found by Coverity Scan. --- libheif/file_fuzzer.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libheif/file_fuzzer.cc b/libheif/file_fuzzer.cc index 376a3060c0..96a2e44b60 100644 --- a/libheif/file_fuzzer.cc +++ b/libheif/file_fuzzer.cc @@ -33,7 +33,8 @@ static void TestDecodeImage(struct heif_context* ctx, struct heif_image* image; struct heif_error err; - heif_image_handle_is_primary_image(handle); + bool primary = heif_image_handle_is_primary_image(handle); + (void) primary; int width = heif_image_handle_get_width(handle); int height = heif_image_handle_get_height(handle); assert(width >= 0); From bcd96261e4fe0f7ce6e025ca0628ec23c724574f Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 14 May 2021 09:39:20 +0200 Subject: [PATCH 0019/3088] Add assertion to help static code analysis. --- libheif/heif_decoder_libde265.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libheif/heif_decoder_libde265.cc b/libheif/heif_decoder_libde265.cc index ad76df1cd4..3e04b76f3b 100644 --- a/libheif/heif_decoder_libde265.cc +++ b/libheif/heif_decoder_libde265.cc @@ -27,6 +27,7 @@ #include "config.h" #endif +#include #include #include @@ -336,6 +337,7 @@ static struct heif_error libde265_v1_decode_image(void* decoder_raw, nclx->set_colour_primaries((uint16_t)de265_get_image_colour_primaries(image)); nclx->set_transfer_characteristics((uint16_t)de265_get_image_transfer_characteristics(image)); #endif + assert(*out_img); (*out_img)->image->set_color_profile_nclx(nclx); de265_release_next_picture(decoder->ctx); From 98b867ea575ecce7039458b71f2c320742489e30 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Tue, 14 Dec 2021 12:18:00 +0100 Subject: [PATCH 0020/3088] Return error if no SPS / no encoded width or height. --- libheif/heif_context.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index 871d78244e..3eac29fc95 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -1966,8 +1966,8 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, err.message); } - int encoded_width = image->get_width(heif_channel_Y); - int encoded_height = image->get_height(heif_channel_Y); + int encoded_width = 0; + int encoded_height = 0; for (;;) { uint8_t* data; @@ -2002,6 +2002,10 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, } } + if (!encoded_width || !encoded_height) { + return Error(heif_error_Encoder_plugin_error, + heif_suberror_Invalid_image_size); + } // if image size was rounded up to even size, add a 'clap' box to crop the // padding border away From 0d7c5a181905eeb6b5bc2c8f91012a2abb0c5bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20Komar=C4=8Devi=C4=87?= Date: Tue, 14 Dec 2021 21:25:44 +0100 Subject: [PATCH 0021/3088] Enable wide chars for all Windows --- libheif/heif.cc | 2 +- libheif/heif_file.cc | 8 ++++---- libheif/heif_file.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libheif/heif.cc b/libheif/heif.cc index 0ce51531b8..dea7309a0a 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -1513,7 +1513,7 @@ static struct heif_error heif_file_writer_write(struct heif_context* ctx, { const char* filename = static_cast(userdata); -#ifdef _MSC_VER +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) std::ofstream ostr(HeifFile::convert_utf8_path_to_utf16(filename).c_str(), std::ios_base::binary); #else std::ofstream ostr(filename, std::ios_base::binary); diff --git a/libheif/heif_file.cc b/libheif/heif_file.cc index 483bf2d89a..100dcac824 100644 --- a/libheif/heif_file.cc +++ b/libheif/heif_file.cc @@ -27,13 +27,13 @@ #include #include -#ifdef _MSC_VER +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) #ifndef NOMINMAX #define NOMINMAX 1 #endif -#include +#include #endif using namespace heif; @@ -66,7 +66,7 @@ std::vector HeifFile::get_item_IDs() const Error HeifFile::read_from_file(const char* input_filename) { -#ifdef _MSC_VER +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) auto input_stream_istr = std::unique_ptr(new std::ifstream(convert_utf8_path_to_utf16(input_filename).c_str(), std::ios_base::binary)); #else auto input_stream_istr = std::unique_ptr(new std::ifstream(input_filename, std::ios_base::binary)); @@ -876,7 +876,7 @@ void HeifFile::set_hdlr_library_info(std::string encoder_plugin_version) } -#ifdef _MSC_VER +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) std::wstring HeifFile::convert_utf8_path_to_utf16(std::string str) { std::wstring ret; diff --git a/libheif/heif_file.h b/libheif/heif_file.h index b053d391d2..f2ca953df9 100644 --- a/libheif/heif_file.h +++ b/libheif/heif_file.h @@ -155,7 +155,7 @@ namespace heif { // TODO: the hdlr box is probably not the right place for this. Into which box should we write comments? void set_hdlr_library_info(std::string encoder_plugin_version); -#ifdef _MSC_VER +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) static std::wstring convert_utf8_path_to_utf16(std::string pathutf8); #endif From 0629f47f2d7e2d5716e271c7b1c7f31549e2b0c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Dec 2021 13:12:42 +0000 Subject: [PATCH 0022/3088] Bump actions/upload-artifact from 2.3.0 to 2.3.1 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2.3.0 to 2.3.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2.3.0...v2.3.1) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/cifuzz.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 921f12c9ca..7eb22a7fcf 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -17,7 +17,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v2.3.0 + uses: actions/upload-artifact@v2.3.1 if: failure() && steps.build.outcome == 'success' with: name: artifacts From ec22c54d3fccbae40758076572c13a1bf29e681d Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Tue, 25 Jan 2022 15:55:49 -0800 Subject: [PATCH 0023/3088] Remove reference to "XMP" in add_generic_metadata Remove a reference to "XMP" in a comment in the add_generic_metadata() method. This method is used to add all kinds of data, not just XMP data. --- libheif/heif_context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index d536c0f9c0..d87c382446 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -2481,7 +2481,7 @@ Error HeifContext::add_generic_metadata(std::shared_ptr master_image, con fourcc("cdsc"), {master_image->get_id()}); - // copy the XMP data into the file, store the pointer to it in an iloc box entry + // copy the data into the file, store the pointer to it in an iloc box entry std::vector data_array; data_array.resize(size); From 7be6f1a0d82dc8a746a56e1bf4d108b2f1c150e3 Mon Sep 17 00:00:00 2001 From: Nicholas Hayes <0xC0000054@users.noreply.github.com> Date: Tue, 1 Feb 2022 21:16:20 -0700 Subject: [PATCH 0024/3088] Add separate quality options for the alpha image This allows callers to use different compression settings for the color and alpha images. --- libheif/heif_encoder_aom.cc | 129 ++++++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 5 deletions(-) diff --git a/libheif/heif_encoder_aom.cc b/libheif/heif_encoder_aom.cc index 5ac4212587..4151699b9f 100644 --- a/libheif/heif_encoder_aom.cc +++ b/libheif/heif_encoder_aom.cc @@ -44,15 +44,25 @@ struct encoder_struct_aom int cpu_used; // = parameter 'speed'. I guess this is a better name than 'cpu_used'. int quality; + int alpha_quality; int min_q; int max_q; + int alpha_min_q; + int alpha_max_q; int threads; bool lossless; + bool lossless_alpha; aom_tune_metric tune; heif_chroma chroma = heif_chroma_420; + // --- input + + bool alpha_quality_set = false; + bool alpha_min_q_set = false; + bool alpha_max_q_set = false; + // --- output std::vector compressedData; @@ -64,6 +74,10 @@ static const char* kError_encode_frame = "Failed to encode frame"; static const char* kParam_min_q = "min-q"; static const char* kParam_max_q = "max-q"; +static const char* kParam_alpha_quality = "alpha-quality"; +static const char* kParam_alpha_min_q = "alpha-min-q"; +static const char* kParam_alpha_max_q = "alpha-max-q"; +static const char* kParam_lossless_alpha = "lossless-alpha"; static const char* kParam_threads = "threads"; static const char* kParam_realtime = "realtime"; static const char* kParam_speed = "speed"; @@ -101,7 +115,7 @@ static const char* aom_plugin_name() } -#define MAX_NPARAMETERS 10 +#define MAX_NPARAMETERS 14 static struct heif_encoder_parameter aom_encoder_params[MAX_NPARAMETERS]; static const struct heif_encoder_parameter* aom_encoder_parameter_ptrs[MAX_NPARAMETERS + 1]; @@ -217,6 +231,50 @@ static void aom_init_parameters() p->integer.num_valid_values = 0; d[i++] = p++; + assert(i < MAX_NPARAMETERS); + p->version = 2; + p->name = kParam_alpha_quality; + p->type = heif_encoder_parameter_type_integer; + p->has_default = false; + p->integer.have_minimum_maximum = true; + p->integer.minimum = 0; + p->integer.maximum = 100; + p->integer.valid_values = NULL; + p->integer.num_valid_values = 0; + d[i++] = p++; + + assert(i < MAX_NPARAMETERS); + p->version = 2; + p->name = kParam_alpha_min_q; + p->type = heif_encoder_parameter_type_integer; + p->has_default = false; + p->integer.have_minimum_maximum = true; + p->integer.minimum = 1; + p->integer.maximum = 62; + p->integer.valid_values = NULL; + p->integer.num_valid_values = 0; + d[i++] = p++; + + assert(i < MAX_NPARAMETERS); + p->version = 2; + p->name = kParam_alpha_max_q; + p->type = heif_encoder_parameter_type_integer; + p->has_default = false; + p->integer.have_minimum_maximum = true; + p->integer.minimum = 0; + p->integer.maximum = 63; + p->integer.valid_values = NULL; + p->integer.num_valid_values = 0; + d[i++] = p++; + + assert(i < MAX_NPARAMETERS); + p->version = 2; + p->name = kParam_lossless_alpha; + p->type = heif_encoder_parameter_type_boolean; + p->boolean.default_value = false; + p->has_default = true; + d[i++] = p++; + d[i++] = nullptr; } @@ -287,6 +345,10 @@ struct heif_error aom_set_parameter_lossless(void* encoder_raw, int enable) if (enable) { encoder->min_q = 0; encoder->max_q = 0; + encoder->alpha_min_q = 0; + encoder->alpha_min_q_set = true; + encoder->alpha_max_q = 0; + encoder->alpha_max_q_set = true; } encoder->lossless = enable; @@ -345,6 +407,25 @@ struct heif_error aom_set_parameter_integer(void* encoder_raw, const char* name, else if (strcmp(name, heif_encoder_parameter_name_lossless) == 0) { return aom_set_parameter_lossless(encoder, value); } + else if (strcmp(name, kParam_alpha_quality) == 0) { + if (value < 0 || value > 100) { + return heif_error_invalid_parameter_value; + } + + encoder->alpha_quality = value; + encoder->alpha_quality_set = true; + return heif_error_ok; + } + else if (strcmp(name, kParam_alpha_min_q) == 0) { + encoder->alpha_min_q = value; + encoder->alpha_min_q_set = true; + return heif_error_ok; + } + else if (strcmp(name, kParam_alpha_max_q) == 0) { + encoder->alpha_max_q = value; + encoder->alpha_max_q_set = true; + return heif_error_ok; + } set_value(kParam_min_q, min_q); set_value(kParam_max_q, max_q); @@ -364,6 +445,18 @@ struct heif_error aom_get_parameter_integer(void* encoder_raw, const char* name, else if (strcmp(name, heif_encoder_parameter_name_lossless) == 0) { return aom_get_parameter_lossless(encoder, value); } + else if (strcmp(name, kParam_alpha_quality) == 0) { + *value = encoder->alpha_quality_set ? encoder->alpha_quality : encoder->quality; + return heif_error_ok; + } + else if (strcmp(name, kParam_alpha_max_q) == 0) { + *value = encoder->alpha_max_q_set ? encoder->alpha_max_q : encoder->max_q; + return heif_error_ok; + } + else if (strcmp(name, kParam_alpha_min_q) == 0) { + *value = encoder->alpha_min_q_set ? encoder->alpha_min_q : encoder->min_q; + return heif_error_ok; + } get_value(kParam_min_q, min_q); get_value(kParam_max_q, max_q); @@ -381,6 +474,16 @@ struct heif_error aom_set_parameter_boolean(void* encoder_raw, const char* name, if (strcmp(name, heif_encoder_parameter_name_lossless) == 0) { return aom_set_parameter_lossless(encoder, value); } + else if (strcmp(name, kParam_lossless_alpha) == 0) { + encoder->lossless_alpha = value; + if (value) { + encoder->alpha_max_q = 0; + encoder->alpha_max_q_set = true; + encoder->alpha_min_q = 0; + encoder->alpha_min_q_set = true; + } + return heif_error_ok; + } set_value(kParam_realtime, realtime_mode); @@ -396,6 +499,7 @@ struct heif_error aom_get_parameter_boolean(void* encoder_raw, const char* name, } get_value(kParam_realtime, realtime_mode); + get_value(kParam_lossless_alpha, lossless_alpha); return heif_error_unsupported_parameter; } @@ -728,8 +832,17 @@ struct heif_error aom_encode_image(void* encoder_raw, const struct heif_image* i cfg.g_input_bit_depth = bpp_y; cfg.rc_end_usage = AOM_Q; - cfg.rc_min_quantizer = encoder->min_q; - cfg.rc_max_quantizer = encoder->max_q; + + int min_q = encoder->min_q; + int max_q = encoder->max_q; + + if (input_class == heif_image_input_class_alpha && encoder->alpha_min_q_set && encoder->alpha_max_q_set) { + min_q = encoder->alpha_min_q; + max_q = encoder->alpha_max_q; + } + + cfg.rc_min_quantizer = min_q; + cfg.rc_max_quantizer = max_q; cfg.g_error_resilient = 0; cfg.g_threads = encoder->threads; @@ -753,7 +866,13 @@ struct heif_error aom_encode_image(void* encoder_raw, const struct heif_image* i aom_codec_control(&codec, AOME_SET_CPUUSED, encoder->cpu_used); - int cq_level = ((100 - encoder->quality) * 63 + 50) / 100; + int quality = encoder->quality; + + if (input_class == heif_image_input_class_alpha && encoder->alpha_quality_set) { + quality = encoder->alpha_quality; + } + + int cq_level = ((100 - quality) * 63 + 50) / 100; aom_codec_control(&codec, AOME_SET_CQ_LEVEL, cq_level); if (encoder->threads > 1) { @@ -780,7 +899,7 @@ struct heif_error aom_encode_image(void* encoder_raw, const struct heif_image* i aom_codec_control(&codec, AOME_SET_TUNING, encoder->tune); - if (encoder->lossless) { + if (encoder->lossless || input_class == heif_image_input_class_alpha && encoder->lossless_alpha) { aom_codec_control(&codec, AV1E_SET_LOSSLESS, 1); } From 0082fea96ee70a20c8906a0373bedec0c01777bc Mon Sep 17 00:00:00 2001 From: Alexander Piskun <13381981+bigcat88@users.noreply.github.com> Date: Wed, 2 Feb 2022 10:28:02 +0200 Subject: [PATCH 0025/3088] Added pillow_heif for python bindings (#598) Difference from pyheif: 1. Builds publicly on GitHub 2. Wheels for Linux, Alpine, macOS - x64, aarch64(arm64) 3. read_color_profile/read_metadata differs from pyheif(see 4) 4. Use it myself in public project(Nextcloud), heavily tested by admins, fast bug reports. 5. Contains some features that pyheif still hasn't. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3e1933692..8f598894ea 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ When running `cmake` or `configure`, make sure that the environment variable * Go: part of libheif * JavaScript: by compilation with emscripten (see below) * NodeJS module: [libheif-js](https://www.npmjs.com/package/libheif-js) -* Python: [pyheif](https://pypi.org/project/pyheif/) +* Python: [pyheif](https://pypi.org/project/pyheif/), [pillow_heif](https://pypi.org/project/pillow-heif/) * Rust: [libheif-sys](https://github.com/Cykooz/libheif-sys) * Swift: [libheif-Xcode](https://swiftpackageregistry.com/SDWebImage/libheif-Xcode) From ae5dfce9b625bd832b83e6a30d721bf1570a718e Mon Sep 17 00:00:00 2001 From: Nicholas Hayes <0xC0000054@users.noreply.github.com> Date: Thu, 3 Feb 2022 04:37:26 -0700 Subject: [PATCH 0026/3088] Add support for the AOM key=value API This allows callers to pass custom options to the AOM encoder by adding an 'aom:' prefix to the option name. Th custom options will be applied after libheif configures the default options because they can override the values that were set. The x265 encoder already has a similar feature with the 'x265:' prefix. Resolves #596 --- libheif/heif_encoder_aom.cc | 65 +++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/libheif/heif_encoder_aom.cc b/libheif/heif_encoder_aom.cc index 5ac4212587..f14adc5895 100644 --- a/libheif/heif_encoder_aom.cc +++ b/libheif/heif_encoder_aom.cc @@ -35,6 +35,19 @@ #include #include +// Detect whether the aom_codec_set_option() function is available. +// See https://aomedia.googlesource.com/aom/+/c1d42fe6615c96fc929257ed53c41fa094f38836%5E%21/aom/aom_codec.h. +#if AOM_CODEC_ABI_VERSION >= (6 + AOM_IMAGE_ABI_VERSION) +#define HAVE_AOM_CODEC_SET_OPTION 1 +#endif + +#if defined(HAVE_AOM_CODEC_SET_OPTION) +struct custom_option +{ + std::string name; + std::string value; +}; +#endif struct encoder_struct_aom { @@ -49,6 +62,14 @@ struct encoder_struct_aom int threads; bool lossless; +#if defined(HAVE_AOM_CODEC_SET_OPTION) + std::vector custom_options; + + void add_custom_option(const custom_option&); + + void add_custom_option(std::string name, std::string value); +#endif + aom_tune_metric tune; heif_chroma chroma = heif_chroma_420; @@ -59,6 +80,35 @@ struct encoder_struct_aom bool data_read = false; }; +#if defined(HAVE_AOM_CODEC_SET_OPTION) +void encoder_struct_aom::add_custom_option(const custom_option& p) +{ + // if there is already a parameter of that name, remove it from list + + for (size_t i = 0; i < custom_options.size(); i++) { + if (custom_options[i].name == p.name) { + for (size_t k = i + 1; k < custom_options.size(); k++) { + custom_options[k - 1] = custom_options[k]; + } + custom_options.pop_back(); + break; + } + } + + // and add the new parameter at the end of the list + + custom_options.push_back(p); +} + +void encoder_struct_aom::add_custom_option(std::string name, std::string value) +{ + custom_option p; + p.name = name; + p.value = value; + add_custom_option(p); +} +#endif + static const char* kError_out_of_memory = "Out of memory"; static const char* kError_encode_frame = "Failed to encode frame"; @@ -437,6 +487,13 @@ struct heif_error aom_set_parameter_string(void* encoder_raw, const char* name, } } +#if defined(HAVE_AOM_CODEC_SET_OPTION) + if (strncmp(name, "aom:", 4) == 0) { + encoder->add_custom_option(std::string(name).substr(4), std::string(value)); + return heif_error_ok; + } +#endif + return heif_error_unsupported_parameter; } @@ -784,6 +841,14 @@ struct heif_error aom_encode_image(void* encoder_raw, const struct heif_image* i aom_codec_control(&codec, AV1E_SET_LOSSLESS, 1); } +#if defined(HAVE_AOM_CODEC_SET_OPTION) + // Apply the custom AOM encoder options. + // These should always be applied last as they can override the values that were set above. + for (const auto& p : encoder->custom_options) { + aom_codec_set_option(&codec, p.name.c_str(), p.value.c_str()); + } +#endif + // --- encode frame err = encode_frame(&codec, &input_image); //, frame_count++, flags, writer); From 899486a32e7fb5afe42765adfc1f12b274358fe7 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Sat, 19 Feb 2022 19:26:11 +0100 Subject: [PATCH 0027/3088] put parentheses around logical expression to increase readability --- examples/heif_enc.cc | 1 - libheif/heif_decoder_aom.cc | 3 +++ libheif/heif_encoder_aom.cc | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 7ba18f1f64..4729adef3b 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -1235,7 +1235,6 @@ int main(int argc, char** argv) heif_encoder_set_logging_level(encoder, logging_level); set_params(encoder, raw_params); - struct heif_encoding_options* options = heif_encoding_options_alloc(); options->save_alpha_channel = (uint8_t) master_alpha; options->save_two_colr_boxes_when_ICC_and_nclx_available = (uint8_t)two_colr_boxes; diff --git a/libheif/heif_decoder_aom.cc b/libheif/heif_decoder_aom.cc index 817c5d83f3..3a4ac46fbd 100644 --- a/libheif/heif_decoder_aom.cc +++ b/libheif/heif_decoder_aom.cc @@ -130,6 +130,9 @@ struct heif_error aom_push_data(void* decoder_raw, const void* frame_data, size_ { struct aom_decoder* decoder = (struct aom_decoder*) decoder_raw; + const char* ver = aom_codec_version_str(); + (void)ver; + aom_codec_err_t aomerr; aomerr = aom_codec_decode(&decoder->codec, (const uint8_t*) frame_data, frame_size, NULL); if (aomerr) { diff --git a/libheif/heif_encoder_aom.cc b/libheif/heif_encoder_aom.cc index 3ac4df9364..2a03565498 100644 --- a/libheif/heif_encoder_aom.cc +++ b/libheif/heif_encoder_aom.cc @@ -956,7 +956,7 @@ struct heif_error aom_encode_image(void* encoder_raw, const struct heif_image* i aom_codec_control(&codec, AOME_SET_TUNING, encoder->tune); - if (encoder->lossless || input_class == heif_image_input_class_alpha && encoder->lossless_alpha) { + if (encoder->lossless || (input_class == heif_image_input_class_alpha && encoder->lossless_alpha)) { aom_codec_control(&codec, AV1E_SET_LOSSLESS, 1); } From 8c5465e3a80db00bc5d033c7313a0a6314462f1b Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Sat, 19 Feb 2022 19:36:27 +0100 Subject: [PATCH 0028/3088] cast size_t to int (MultiByteToWideChar) --- libheif/heif_file.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libheif/heif_file.cc b/libheif/heif_file.cc index 100dcac824..0a685ad279 100644 --- a/libheif/heif_file.cc +++ b/libheif/heif_file.cc @@ -880,11 +880,11 @@ void HeifFile::set_hdlr_library_info(std::string encoder_plugin_version) std::wstring HeifFile::convert_utf8_path_to_utf16(std::string str) { std::wstring ret; - int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); + int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.length(), NULL, 0); if (len > 0) { ret.resize(len); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &ret[0], len); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.length(), &ret[0], len); } return ret; } From fa3ede77bfb744c941ba39458192a80c59680034 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Sat, 19 Feb 2022 20:21:22 +0100 Subject: [PATCH 0029/3088] Revert "Merge pull request #565 from xyproto/master" This reverts commit a91dc23009822c436fbf2d1ea7c9eb2556402afe, reversing changes made to 8c5465e3a80db00bc5d033c7313a0a6314462f1b. --- go/Makefile.am | 4 +- go/heif/go.mod | 15 --- go/heif/go.sum | 25 ----- go/heif/heif.go | 2 + go/heif/keepalive_16.go | 1 - go/heif/keepalive_17.go | 1 - go/heif/metadata.go | 216 --------------------------------------- go/heif/metadata_test.go | 72 ------------- 8 files changed, 3 insertions(+), 333 deletions(-) delete mode 100644 go/heif/go.mod delete mode 100644 go/heif/go.sum delete mode 100644 go/heif/metadata.go delete mode 100644 go/heif/metadata_test.go diff --git a/go/Makefile.am b/go/Makefile.am index 7c9cfcacb4..329261e457 100644 --- a/go/Makefile.am +++ b/go/Makefile.am @@ -2,9 +2,7 @@ EXTRA_DIST = \ heif/heif.go \ heif/heif_test.go \ heif/keepalive_16.go \ - heif/keepalive_17.go \ - heif/metadata.go \ - heif/metadata_test.go + heif/keepalive_17.go gopath: ln -sf ${CURDIR} ${CURDIR}/src diff --git a/go/heif/go.mod b/go/heif/go.mod deleted file mode 100644 index a5f79971a2..0000000000 --- a/go/heif/go.mod +++ /dev/null @@ -1,15 +0,0 @@ -module github.com/strukturag/libheif/go/heif - -go 1.17 - -require ( - github.com/antchfx/xmlquery v1.3.8 - github.com/antchfx/xpath v1.2.0 - howett.net/plist v0.0.0-20201203080718-1454fab16a06 -) - -require ( - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect - golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc // indirect - golang.org/x/text v0.3.0 // indirect -) diff --git a/go/heif/go.sum b/go/heif/go.sum deleted file mode 100644 index 799da5dde7..0000000000 --- a/go/heif/go.sum +++ /dev/null @@ -1,25 +0,0 @@ -github.com/antchfx/xmlquery v1.3.8 h1:dRnBQM3Vk5BVJFvFwsHOLAox+mEiNw5ZusaUNCrEdoU= -github.com/antchfx/xmlquery v1.3.8/go.mod h1:wojC/BxjEkjJt6dPiAqUzoXO5nIMWtxHS8PD8TmN4ks= -github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8= -github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -howett.net/plist v0.0.0-20201203080718-1454fab16a06 h1:QDxUo/w2COstK1wIBYpzQlHX/NqaQTcf9jyz347nI58= -howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= diff --git a/go/heif/heif.go b/go/heif/heif.go index be6fc78d65..d2ee918f96 100644 --- a/go/heif/heif.go +++ b/go/heif/heif.go @@ -587,6 +587,8 @@ func (h *ImageHandle) GetThumbnail(thumbnail_id int) (*ImageHandle, error) { return &handle, convertHeifError(err) } +// TODO: EXIF metadata + // --- Image type DecodingOptions struct { diff --git a/go/heif/keepalive_16.go b/go/heif/keepalive_16.go index 5d416ed9dc..ef6941d5e4 100644 --- a/go/heif/keepalive_16.go +++ b/go/heif/keepalive_16.go @@ -1,4 +1,3 @@ -//go:build !go1.7 // +build !go1.7 /* diff --git a/go/heif/keepalive_17.go b/go/heif/keepalive_17.go index 242cd3c051..d5b5d85a27 100644 --- a/go/heif/keepalive_17.go +++ b/go/heif/keepalive_17.go @@ -1,4 +1,3 @@ -//go:build go1.7 // +build go1.7 /* diff --git a/go/heif/metadata.go b/go/heif/metadata.go deleted file mode 100644 index afb7a23ecd..0000000000 --- a/go/heif/metadata.go +++ /dev/null @@ -1,216 +0,0 @@ -package heif - -/* - * GO interface to libheif - * Copyright (c) 2021 Alexander F. Rødseth - * - * This file is part of heif, an example application using libheif. - * - * heif is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * heif is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with heif. If not, see . - */ - -/* -#cgo pkg-config: libheif -#include -#include -#include -*/ -import "C" - -import ( - "bytes" - "encoding/base64" - "errors" - "math" - "time" - "unsafe" - - "github.com/antchfx/xmlquery" - "github.com/antchfx/xpath" - "howett.net/plist" -) - -type ( - // MetadataID contains an uint that represents the ID of a block of metadata - MetadataID uint - - // TimeTable maps from image index to a time.Time that contains the hour and minute for a dynamic wallpaper image - TimeTable []time.Time -) - -var ( - errH24 = errors.New("unusual apple_desktop:h24 metadata") -) - -func (h *ImageHandle) MetadataCount() int { - n := int(C.heif_image_handle_get_number_of_metadata_blocks(h.handle, nil)) - keepAlive(h) - return n -} - -func (h *ImageHandle) MetadataIDs() []MetadataID { - nMeta := h.MetadataCount() - if nMeta == 0 { - return []MetadataID{} - } - meta := make([]C.uint, nMeta) - - C.heif_image_handle_get_list_of_metadata_block_IDs(h.handle, nil, &meta[0], C.int(nMeta)) - keepAlive(h) - metaDataIDs := make([]MetadataID, nMeta) - for i := 0; i < nMeta; i++ { - metaDataIDs[i] = MetadataID(meta[i]) - } - return metaDataIDs -} - -func (h *ImageHandle) Metadata(mID MetadataID) []byte { - nMeta := h.MetadataCount() - if nMeta == 0 { - return []byte{} - } - - nData := C.heif_image_handle_get_metadata_size(h.handle, C.uint(mID)) - keepAlive(h) - - data := C.malloc(C.sizeof_char * nData) - defer C.free(unsafe.Pointer(data)) - - C.heif_image_handle_get_metadata(h.handle, C.uint(mID), data) - keepAlive(h) - - return C.GoBytes(data, C.int(nData)) -} - -func (h *ImageHandle) ExifCount() int { - filter := C.CString("Exif") - defer C.free(unsafe.Pointer(filter)) - n := int(C.heif_image_handle_get_number_of_metadata_blocks(h.handle, filter)) - keepAlive(h) - return n -} - -func (h *ImageHandle) ExifIDs() []MetadataID { - nMeta := h.ExifCount() - if nMeta == 0 { - return []MetadataID{} - } - filter := C.CString("Exif") - defer C.free(unsafe.Pointer(filter)) - meta := make([]C.uint, nMeta) - C.heif_image_handle_get_list_of_metadata_block_IDs(h.handle, filter, &meta[0], C.int(nMeta)) - keepAlive(h) - metaDataIDs := make([]MetadataID, nMeta) - for i := 0; i < nMeta; i++ { - metaDataIDs[i] = MetadataID(meta[i]) - } - return metaDataIDs -} - -// MetadataMap takes a metadata ID and an XPath expression -// Within the metadata there may be XML, within the XML there may be a Base64 encoded string, -// and within the Base64 encoded string there may be a propery list in the Apple plist format -// and within that plist there may be a timestamp or solar position, -// encoded in the form of a property list. Oh joy. -func (h *ImageHandle) MetadataMap(mID MetadataID, xs string) (map[string]interface{}, error) { - xmlData := bytes.ReplaceAll(h.Metadata(mID), []byte{0}, []byte{}) - expr, err := xpath.Compile(xs) - if err != nil { - return nil, err - } - doc, err := xmlquery.Parse(bytes.NewReader(xmlData)) - if err != nil { - return nil, err - } - base64string, ok := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(string) - if !ok { - return nil, errors.New("could not find string at " + xs) - } - b64decoded, err := base64.StdEncoding.DecodeString(base64string) - if err != nil { - return nil, err - } - decodedMap := make(map[string]interface{}) - _, err = plist.Unmarshal(b64decoded, &decodedMap) - if err != nil { - return nil, err - } - return decodedMap, nil -} - -func (h *ImageHandle) AppleTimesMap(mID MetadataID) (map[string]interface{}, error) { - return h.MetadataMap(mID, "string(//x:xmpmeta/rdf:RDF/rdf:Description/@apple_desktop:h24)") -} - -func (h *ImageHandle) AppleSolarMap(mID MetadataID) (map[string]interface{}, error) { - return h.MetadataMap(mID, "string(//x:xmpmeta/rdf:RDF/rdf:Description/@apple_desktop:solar)") -} - -// ImageTimes returns the image times for a dynamic wallpaper. -func (h *ImageHandle) ImageTimes(mID MetadataID) (TimeTable, error) { - m, err := h.AppleTimesMap(mID) - if err != nil { - return nil, err - } - - // TODO: m["ap"] is ignored for now. It should have an "l" and "d" key but it's unclear what those might be. - // Perhaps longitude and latitude? - - tiMapList, found := m["ti"] - if !found { - return nil, err - } - tii, ok := tiMapList.([]interface{}) - if !ok { - return nil, errH24 - } - imageTimes := make(TimeTable, len(tii)) - for _, tiMap := range tii { - tiMapMap, ok := tiMap.(map[string]interface{}) - if !ok { - return nil, errH24 - } - iDuck, ok := tiMapMap["i"] - if !ok { - return nil, errH24 - } - tDuck, ok := tiMapMap["t"] - if !ok { - return nil, errH24 - } - iValue, ok := iDuck.(uint64) - if !ok { - return nil, errH24 - } - tValue, ok := tDuck.(float64) - if !ok { - return nil, errH24 - } - imageIndex := iValue - imageHourFloat := tValue * 24.0 - imageHourInt := int(math.Floor(imageHourFloat)) - imageMinuteFloat := (imageHourFloat - float64(imageHourInt)) * 60.0 - imageMinuteInt := int(math.Floor(imageMinuteFloat)) - - // Generate a time.Time that contains the correct hour and minute - now := time.Now() - timeWithHourAndMinute := time.Date(now.Year(), now.Month(), now.Day(), imageHourInt, imageMinuteInt, 0, 0, now.Location()) - - // For the found imageIndex, set the time.Time - imageTimes[imageIndex] = timeWithHourAndMinute - } - return imageTimes, nil -} - -// TODO: Also create a function that pulls out contents from the results of AppleSolarMap diff --git a/go/heif/metadata_test.go b/go/heif/metadata_test.go deleted file mode 100644 index 61e3a90dce..0000000000 --- a/go/heif/metadata_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package heif - -import ( - "fmt" - "os" - "path" - "testing" -) - -// exists checks if the given path exists -func exists(path string) bool { - _, err := os.Stat(path) - return err == nil -} - -func TestExifCount(t *testing.T) { - ctx, err := NewContext() - if err != nil { - t.Fatalf("Can't create context: %s", err) - } - - imageFilename := path.Join("..", "..", "examples", "mont.heic") - - if !exists(imageFilename) { - // skip the test, since the image is not available in the repositry, for copyright reasons - // the test image can be downloaded from: - // https://dynamicwallpaper.club/wallpaper/la4wfuwtkg - return - } - - if err := ctx.ReadFromFile(imageFilename); err != nil { - t.Fatalf("Can't read from %s: %s", imageFilename, err) - } - - if count := ctx.GetNumberOfTopLevelImages(); count != 16 { - t.Errorf("Expected %d top level images, got %d", 16, count) - } - if ids := ctx.GetListOfTopLevelImageIDs(); len(ids) != 16 { - t.Errorf("Expected %d top level image ids, got %+v", 16, ids) - } - if _, err := ctx.GetPrimaryImageID(); err != nil { - t.Errorf("Expected a primary image, got %s", err) - } - handle, err := ctx.GetPrimaryImageHandle() - if err != nil { - t.Errorf("Could not get primary image handle: %s", err) - } - if !handle.IsPrimaryImage() { - t.Error("Expected primary image") - } - - exifCount := handle.ExifCount() - fmt.Println("Exif count", exifCount) - - exifIDs := handle.ExifIDs() - fmt.Println("Exif IDs", exifIDs) - - metadataCount := handle.MetadataCount() - fmt.Println("Metadata count", metadataCount) - - metadataIDs := handle.MetadataIDs() - fmt.Println("Metadata IDs", metadataIDs) - - metadataID := metadataIDs[0] - - times, err := handle.ImageTimes(metadataID) - if err != nil { - t.Fail() - } - - fmt.Println(times) -} From e288894fd7f1d563e23eb5bb63934794a74f82ee Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 21 Feb 2022 09:02:55 +0100 Subject: [PATCH 0030/3088] Optimize passing of variables to avoid unnecessary copies. Found by clang-tidy. --- examples/heif_enc.cc | 4 +- examples/heif_test.cc | 2 +- examples/heif_thumbnailer.cc | 6 +- libheif/bitstream.cc | 6 +- libheif/box.cc | 8 +- libheif/box.h | 37 ++-- libheif/error.cc | 2 +- libheif/error.h | 4 +- libheif/heif.cc | 26 +-- libheif/heif_avif.cc | 2 +- libheif/heif_avif.h | 2 +- libheif/heif_colorconversion.cc | 370 ++++++++++++++++---------------- libheif/heif_colorconversion.h | 18 +- libheif/heif_context.cc | 106 ++++----- libheif/heif_context.h | 30 +-- libheif/heif_cxx.h | 43 ++-- libheif/heif_encoder_x265.cc | 20 +- libheif/heif_file.cc | 10 +- libheif/heif_file.h | 10 +- libheif/heif_image.h | 8 +- 20 files changed, 360 insertions(+), 354 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 4729adef3b..00c4f9f2df 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -972,9 +972,9 @@ void list_encoder_parameters(heif_encoder* encoder) } -void set_params(struct heif_encoder* encoder, std::vector params) +void set_params(struct heif_encoder* encoder, const std::vector& params) { - for (std::string p : params) { + for (const std::string& p : params) { auto pos = p.find_first_of('='); if (pos == std::string::npos || pos == 0 || pos == p.size() - 1) { std::cerr << "Encoder parameter must be in the format 'name=value'\n"; diff --git a/examples/heif_test.cc b/examples/heif_test.cc index e1d38269c8..0cfbdeb63f 100644 --- a/examples/heif_test.cc +++ b/examples/heif_test.cc @@ -68,7 +68,7 @@ void show_help(const char* argv0) } -std::pair parse_id_pair(std::string s) +std::pair parse_id_pair(const std::string& s) { std::string::size_type p = s.find_first_of(':'); if (p == std::string::npos) { diff --git a/examples/heif_thumbnailer.cc b/examples/heif_thumbnailer.cc index 93b2c77baf..7a6408aeab 100644 --- a/examples/heif_thumbnailer.cc +++ b/examples/heif_thumbnailer.cc @@ -158,10 +158,10 @@ int main(int argc, char** argv) int input_width = heif_image_handle_get_width(image_handle); int input_height = heif_image_handle_get_height(image_handle); - int thumbnail_width = input_width; - int thumbnail_height = input_height; - if (input_width > size || input_height > size) { + int thumbnail_width; + int thumbnail_height; + if (input_width > input_height) { thumbnail_height = input_height * size / input_width; thumbnail_width = size; diff --git a/libheif/bitstream.cc b/libheif/bitstream.cc index a0c92415f9..76811cb333 100644 --- a/libheif/bitstream.cc +++ b/libheif/bitstream.cc @@ -148,12 +148,8 @@ StreamReader::grow_status StreamReader_CApi::wait_for_file_size(int64_t target_s BitstreamRange::BitstreamRange(std::shared_ptr istr, uint64_t length, BitstreamRange* parent) + : m_istr(std::move(istr)), m_parent_range(parent), m_remaining(length) { - m_remaining = length; - - m_istr = istr; - m_parent_range = parent; - if (parent) { m_nesting_level = parent->m_nesting_level + 1; } diff --git a/libheif/box.cc b/libheif/box.cc index 2595838551..a44120271c 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -1063,7 +1063,7 @@ std::string Box_iloc::dump(Indent& indent) const Error Box_iloc::read_data(const Item& item, - std::shared_ptr istr, + const std::shared_ptr& istr, const std::shared_ptr& idat, std::vector* dest) const { @@ -1130,6 +1130,7 @@ Error Box_iloc::read_data(const Item& item, dest->resize(static_cast(old_size + extent.length)); success = istr->read((char*) dest->data() + old_size, static_cast(extent.length)); assert(success); + (void) success; } else if (item.construction_method == 1) { if (!idat) { @@ -2596,7 +2597,7 @@ std::vector Box_iref::get_references(uint32_t itemID, uint32_t ref_typ } -void Box_iref::add_reference(heif_item_id from_id, uint32_t type, std::vector to_ids) +void Box_iref::add_reference(heif_item_id from_id, uint32_t type, const std::vector& to_ids) { Reference ref; ref.header.set_short_type(type); @@ -3014,7 +3015,7 @@ std::string Box_idat::dump(Indent& indent) const } -Error Box_idat::read_data(std::shared_ptr istr, +Error Box_idat::read_data(const std::shared_ptr& istr, uint64_t start, uint64_t length, std::vector& out_data) const { @@ -3064,6 +3065,7 @@ Error Box_idat::read_data(std::shared_ptr istr, success = istr->read((char*) data, static_cast(length)); assert(success); + (void) success; } return Error::Ok; diff --git a/libheif/box.h b/libheif/box.h index 2256861d10..f1c8211601 100644 --- a/libheif/box.h +++ b/libheif/box.h @@ -206,7 +206,7 @@ namespace heif { const std::vector>& get_all_child_boxes() const { return m_children; } - int append_child_box(std::shared_ptr box) + int append_child_box(const std::shared_ptr& box) { m_children.push_back(box); return (int) m_children.size() - 1; @@ -245,7 +245,6 @@ namespace heif { std::vector list_brands() const { return m_compatible_brands; } - void set_major_brand(uint32_t major_brand) { m_major_brand = major_brand; } @@ -392,7 +391,7 @@ namespace heif { { return m_items; } Error read_data(const Item& item, - std::shared_ptr istr, + const std::shared_ptr& istr, const std::shared_ptr&, std::vector* dest) const; @@ -464,19 +463,19 @@ namespace heif { void set_item_ID(heif_item_id id) { m_item_ID = id; } - std::string get_item_type() const + const std::string& get_item_type() const { return m_item_type; } - void set_item_type(std::string type) + void set_item_type(const std::string& type) { m_item_type = type; } - void set_item_name(std::string name) + void set_item_name(const std::string& name) { m_item_name = name; } - std::string get_content_type() const + const std::string& get_content_type() const { return m_content_type; } - void set_content_type(std::string content_type) + void set_content_type(const std::string& content_type) { m_content_type = content_type; } void derive_box_version() override; @@ -670,13 +669,13 @@ namespace heif { Box_auxC(const BoxHeader& hdr) : Box(hdr) {} - std::string get_aux_type() const + const std::string& get_aux_type() const { return m_aux_type; } - void set_aux_type(std::string type) + void set_aux_type(const std::string& type) { m_aux_type = type; } - std::vector get_subtypes() const + const std::vector& get_subtypes() const { return m_aux_subtypes; } std::string dump(Indent&) const override; @@ -804,7 +803,7 @@ namespace heif { std::vector get_references_from(heif_item_id itemID) const; - void add_reference(heif_item_id from_id, uint32_t type, std::vector to_ids); + void add_reference(heif_item_id from_id, uint32_t type, const std::vector& to_ids); protected: Error parse(BitstreamRange& range) override; @@ -863,7 +862,7 @@ namespace heif { void set_configuration(const configuration& config) { m_configuration = config; } - configuration get_configuration() const + const configuration& get_configuration() const { return m_configuration; } void append_nal_data(const std::vector& nal); @@ -936,7 +935,7 @@ namespace heif { void set_configuration(const configuration& config) { m_configuration = config; } - configuration get_configuration() const + const configuration& get_configuration() const { return m_configuration; } //void append_nal_data(const std::vector& nal); @@ -962,7 +961,7 @@ namespace heif { std::string dump(Indent&) const override; - Error read_data(std::shared_ptr istr, + Error read_data(const std::shared_ptr& istr, uint64_t start, uint64_t length, std::vector& out_data) const; @@ -1100,14 +1099,14 @@ namespace heif { class color_profile_raw : public color_profile { public: - color_profile_raw(uint32_t type, std::vector data) + color_profile_raw(uint32_t type, const std::vector& data) : m_type(type), m_data(data) {} uint32_t get_type() const override { return m_type; } - std::vector get_data() const + const std::vector& get_data() const { return m_data; } std::string dump(Indent&) const override; @@ -1196,10 +1195,10 @@ namespace heif { uint32_t get_color_profile_type() const { return m_color_profile->get_type(); } - std::shared_ptr get_color_profile() const + const std::shared_ptr& get_color_profile() const { return m_color_profile; } - void set_color_profile(std::shared_ptr prof) + void set_color_profile(const std::shared_ptr& prof) { m_color_profile = prof; } diff --git a/libheif/error.cc b/libheif/error.cc index 75796b99c1..6aabdb5fa9 100644 --- a/libheif/error.cc +++ b/libheif/error.cc @@ -36,7 +36,7 @@ heif::Error::Error() heif::Error::Error(heif_error_code c, heif_suberror_code sc, - std::string msg) + const std::string& msg) : error_code(c), sub_error_code(sc), message(msg) diff --git a/libheif/error.h b/libheif/error.h index bc28be404a..0a2f67949e 100644 --- a/libheif/error.h +++ b/libheif/error.h @@ -56,7 +56,7 @@ namespace heif { m_error_message = c_success; } - void set_error(std::string err) + void set_error(const std::string& err) { m_buffer = err; m_error_message = m_buffer.c_str(); @@ -85,7 +85,7 @@ namespace heif { Error(heif_error_code c, heif_suberror_code sc = heif_suberror_Unspecified, - std::string msg = ""); + const std::string& msg = ""); static Error Ok; diff --git a/libheif/heif.cc b/libheif/heif.cc index 86c7b51dda..082d1e9475 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -140,7 +140,7 @@ heif_brand heif_fourcc_to_brand_enum(const char* fourcc) if (fourcc==nullptr || !fourcc[0] || !fourcc[1] || !fourcc[2] || !fourcc[3]) { return heif_unknown_brand; } - + char brand[5]; brand[0] = fourcc[0]; brand[1] = fourcc[1]; @@ -238,7 +238,7 @@ int heif_has_compatible_brand(const uint8_t* data, int len, const char* brand_fo if (data == nullptr || len<=0 || brand_fourcc == nullptr || !brand_fourcc[0] || !brand_fourcc[1] || !brand_fourcc[2] || !brand_fourcc[3]) { return -1; } - + auto stream = std::make_shared(data, len, false); BitstreamRange range(stream, len); @@ -248,7 +248,7 @@ int heif_has_compatible_brand(const uint8_t* data, int len, const char* brand_fo if (err.sub_error_code == heif_suberror_End_of_data) { return -1; } - + return -2; } @@ -271,7 +271,7 @@ struct heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif if (len<=0) { return {heif_error_Usage_error, heif_suberror_Invalid_parameter_value, "data length must be positive"}; } - + auto stream = std::make_shared(data, len, false); BitstreamRange range(stream, len); @@ -281,7 +281,7 @@ struct heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif if (err.sub_error_code == heif_suberror_End_of_data) { return {err.error_code, err.sub_error_code, "insufficient input data"}; } - + return {err.error_code, err.sub_error_code, "error reading ftyp box"}; } @@ -293,11 +293,11 @@ struct heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif auto brands = ftyp->list_brands(); *out_brands = (heif_brand2*)malloc(sizeof(heif_brand2) * brands.size()); *out_size = (int)brands.size(); - + for (int i=0;i<(int)brands.size();i++) { (*out_brands)[i] = brands[i]; } - + return {heif_error_Ok, heif_suberror_Unspecified, Error::kSuccess}; } @@ -615,7 +615,7 @@ heif_error heif_image_handle_get_thumbnail(const struct heif_image_handle* handl } auto thumbnails = handle->image->get_thumbnails(); - for (auto thumb : thumbnails) { + for (const auto& thumb : thumbnails) { if (thumb->get_id() == thumbnail_id) { *out_thumbnail_handle = new heif_image_handle(); (*out_thumbnail_handle)->image = thumb; @@ -667,13 +667,13 @@ struct heif_error heif_image_handle_get_auxiliary_type(const struct heif_image_h auto auxType = handle->image->get_aux_type(); char* buf = (char*)malloc(auxType.length()+1); - + if (buf == nullptr) { return Error(heif_error_Memory_allocation_error, heif_suberror_Unspecified, "Failed to allocate memory for the type string").error_struct(handle->image.get()); } - + strcpy(buf, auxType.c_str()); *out_type = buf; @@ -701,7 +701,7 @@ struct heif_error heif_image_handle_get_auxiliary_image_handle(const struct heif } auto auxImages = main_image_handle->image->get_aux_images(); - for (auto aux : auxImages) { + for (const auto& aux : auxImages) { if (aux->get_id() == auxiliary_id) { *out_auxiliary_handle = new heif_image_handle(); (*out_auxiliary_handle)->image = aux; @@ -1420,13 +1420,13 @@ struct heif_error heif_image_get_nclx_color_profile(const struct heif_image* ima } auto nclx_profile = image->image->get_color_profile_nclx(); - + if (!nclx_profile) { Error err(heif_error_Color_profile_does_not_exist, heif_suberror_Unspecified); return err.error_struct(image->image.get()); } - + Error err = nclx_profile->get_nclx_color_profile(out_data); return err.error_struct(image->image.get()); diff --git a/libheif/heif_avif.cc b/libheif/heif_avif.cc index 47e858a955..a04d7e6349 100644 --- a/libheif/heif_avif.cc +++ b/libheif/heif_avif.cc @@ -28,7 +28,7 @@ using namespace heif; // https://aomediacodec.github.io/av1-spec/av1-spec.pdf -Error heif::fill_av1C_configuration(Box_av1C::configuration* inout_config, std::shared_ptr image) +Error heif::fill_av1C_configuration(Box_av1C::configuration* inout_config, const std::shared_ptr& image) { int bpp = image->get_bits_per_pixel(heif_channel_Y); heif_chroma chroma = image->get_chroma_format(); diff --git a/libheif/heif_avif.h b/libheif/heif_avif.h index c9744f131d..992d18bb38 100644 --- a/libheif/heif_avif.h +++ b/libheif/heif_avif.h @@ -34,7 +34,7 @@ namespace heif { class HeifPixelImage; - Error fill_av1C_configuration(Box_av1C::configuration* inout_config, std::shared_ptr); + Error fill_av1C_configuration(Box_av1C::configuration* inout_config, const std::shared_ptr& image); bool fill_av1C_configuration_from_stream(Box_av1C::configuration* out_config, const uint8_t* data, int dataSize); diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc index f3b254a6f9..579f299e9c 100644 --- a/libheif/heif_colorconversion.cc +++ b/libheif/heif_colorconversion.cc @@ -153,21 +153,21 @@ class Op_RGB_to_RGB24_32 : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RGB_to_RGB24_32::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RGB_to_RGB24_32::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { if (input_state.colorspace != heif_colorspace_RGB || input_state.chroma != heif_chroma_444 || @@ -221,8 +221,8 @@ Op_RGB_to_RGB24_32::state_after_conversion(ColorState input_state, std::shared_ptr Op_RGB_to_RGB24_32::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { bool has_alpha = input->has_channel(heif_channel_Alpha); bool want_alpha = target_state.has_alpha; @@ -318,22 +318,22 @@ class Op_YCbCr_to_RGB : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; template std::vector -Op_YCbCr_to_RGB::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_YCbCr_to_RGB::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { bool hdr = !std::is_same::value; @@ -368,8 +368,8 @@ Op_YCbCr_to_RGB::state_after_conversion(ColorState input_state, template std::shared_ptr Op_YCbCr_to_RGB::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { bool hdr = !std::is_same::value; @@ -539,22 +539,22 @@ class Op_RGB_to_YCbCr : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; template std::vector -Op_RGB_to_YCbCr::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RGB_to_YCbCr::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { bool hdr = !std::is_same::value; @@ -590,8 +590,8 @@ Op_RGB_to_YCbCr::state_after_conversion(ColorState input_state, template std::shared_ptr Op_RGB_to_YCbCr::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { bool hdr = !std::is_same::value; @@ -776,21 +776,21 @@ class Op_YCbCr420_to_RGB24 : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_YCbCr420_to_RGB24::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_YCbCr420_to_RGB24::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { if (input_state.colorspace != heif_colorspace_YCbCr || input_state.chroma != heif_chroma_420 || @@ -831,8 +831,8 @@ Op_YCbCr420_to_RGB24::state_after_conversion(ColorState input_state, std::shared_ptr Op_YCbCr420_to_RGB24::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { if (input->get_bits_per_pixel(heif_channel_Y) != 8 || input->get_bits_per_pixel(heif_channel_Cb) != 8 || @@ -893,21 +893,21 @@ class Op_YCbCr420_to_RGB32 : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_YCbCr420_to_RGB32::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_YCbCr420_to_RGB32::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -949,8 +949,8 @@ Op_YCbCr420_to_RGB32::state_after_conversion(ColorState input_state, std::shared_ptr Op_YCbCr420_to_RGB32::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { if (input->get_bits_per_pixel(heif_channel_Y) != 8 || input->get_bits_per_pixel(heif_channel_Cb) != 8 || @@ -1030,21 +1030,21 @@ class Op_RGB_HDR_to_RRGGBBaa_BE : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RGB_HDR_to_RRGGBBaa_BE::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RGB_HDR_to_RRGGBBaa_BE::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -1091,8 +1091,8 @@ Op_RGB_HDR_to_RRGGBBaa_BE::state_after_conversion(ColorState input_state, std::shared_ptr Op_RGB_HDR_to_RRGGBBaa_BE::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { if (input->get_bits_per_pixel(heif_channel_R) == 8 || input->get_bits_per_pixel(heif_channel_G) == 8 || @@ -1195,21 +1195,21 @@ class Op_RGB_to_RRGGBBaa_BE : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RGB_to_RRGGBBaa_BE::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RGB_to_RRGGBBaa_BE::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -1256,8 +1256,8 @@ Op_RGB_to_RRGGBBaa_BE::state_after_conversion(ColorState input_state, std::shared_ptr Op_RGB_to_RRGGBBaa_BE::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { if (input->get_bits_per_pixel(heif_channel_R) != 8 || input->get_bits_per_pixel(heif_channel_G) != 8 || @@ -1341,21 +1341,21 @@ class Op_RRGGBBaa_BE_to_RGB_HDR : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RRGGBBaa_BE_to_RGB_HDR::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RRGGBBaa_BE_to_RGB_HDR::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -1390,8 +1390,8 @@ Op_RRGGBBaa_BE_to_RGB_HDR::state_after_conversion(ColorState input_state, std::shared_ptr Op_RRGGBBaa_BE_to_RGB_HDR::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { bool has_alpha = (input->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_LE || input->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_BE); @@ -1466,21 +1466,21 @@ class Op_RRGGBBaa_swap_endianness : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RRGGBBaa_swap_endianness::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RRGGBBaa_swap_endianness::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -1547,8 +1547,8 @@ Op_RRGGBBaa_swap_endianness::state_after_conversion(ColorState input_state, std::shared_ptr Op_RRGGBBaa_swap_endianness::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { auto outimg = std::make_shared(); @@ -1602,21 +1602,21 @@ class Op_mono_to_YCbCr420 : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_mono_to_YCbCr420::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_mono_to_YCbCr420::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -1647,8 +1647,8 @@ Op_mono_to_YCbCr420::state_after_conversion(ColorState input_state, std::shared_ptr Op_mono_to_YCbCr420::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { auto outimg = std::make_shared(); @@ -1751,21 +1751,21 @@ class Op_mono_to_RGB24_32 : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_mono_to_RGB24_32::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_mono_to_RGB24_32::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -1812,8 +1812,8 @@ Op_mono_to_RGB24_32::state_after_conversion(ColorState input_state, std::shared_ptr Op_mono_to_RGB24_32::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { int width = input->get_width(); int height = input->get_height(); @@ -1886,21 +1886,21 @@ class Op_RGB24_32_to_YCbCr : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RGB24_32_to_YCbCr::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RGB24_32_to_YCbCr::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -1989,8 +1989,8 @@ inline void set_chroma_pixels(uint8_t* out_cb, uint8_t* out_cr, std::shared_ptr Op_RGB24_32_to_YCbCr::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { int width = input->get_width(); int height = input->get_height(); @@ -2221,21 +2221,21 @@ class Op_RGB24_32_to_YCbCr444_GBR : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RGB24_32_to_YCbCr444_GBR::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RGB24_32_to_YCbCr444_GBR::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // Note: no input alpha channel required. It will be filled up with 0xFF. @@ -2295,8 +2295,8 @@ Op_RGB24_32_to_YCbCr444_GBR::state_after_conversion(ColorState input_state, std::shared_ptr Op_RGB24_32_to_YCbCr444_GBR::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { int width = input->get_width(); int height = input->get_height(); @@ -2375,21 +2375,21 @@ class Op_drop_alpha_plane : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_drop_alpha_plane::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_drop_alpha_plane::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { // only drop alpha plane if it is not needed in output @@ -2422,8 +2422,8 @@ Op_drop_alpha_plane::state_after_conversion(ColorState input_state, std::shared_ptr Op_drop_alpha_plane::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { int width = input->get_width(); int height = input->get_height(); @@ -2453,21 +2453,21 @@ class Op_to_hdr_planes : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_to_hdr_planes::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_to_hdr_planes::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { if ((input_state.chroma != heif_chroma_monochrome && input_state.chroma != heif_chroma_420 && @@ -2497,8 +2497,8 @@ Op_to_hdr_planes::state_after_conversion(ColorState input_state, std::shared_ptr Op_to_hdr_planes::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { auto outimg = std::make_shared(); @@ -2550,21 +2550,21 @@ class Op_to_sdr_planes : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_to_sdr_planes::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_to_sdr_planes::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { if ((input_state.chroma != heif_chroma_monochrome && input_state.chroma != heif_chroma_420 && @@ -2594,8 +2594,8 @@ Op_to_sdr_planes::state_after_conversion(ColorState input_state, std::shared_ptr Op_to_sdr_planes::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { auto outimg = std::make_shared(); @@ -2651,21 +2651,21 @@ class Op_RRGGBBxx_HDR_to_YCbCr420 : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_RRGGBBxx_HDR_to_YCbCr420::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_RRGGBBxx_HDR_to_YCbCr420::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { if (input_state.colorspace != heif_colorspace_RGB || !(input_state.chroma == heif_chroma_interleaved_RRGGBB_BE || @@ -2709,8 +2709,8 @@ Op_RRGGBBxx_HDR_to_YCbCr420::state_after_conversion(ColorState input_state, std::shared_ptr Op_RRGGBBxx_HDR_to_YCbCr420::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { int width = input->get_width(); int height = input->get_height(); @@ -2848,21 +2848,21 @@ class Op_YCbCr420_to_RRGGBBaa : public ColorConversionOperation { public: std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) override; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) override; std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) override; + const ColorState& target_state, + const ColorConversionOptions& options) override; }; std::vector -Op_YCbCr420_to_RRGGBBaa::state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +Op_YCbCr420_to_RRGGBBaa::state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { if (input_state.colorspace != heif_colorspace_YCbCr || input_state.chroma != heif_chroma_420 || @@ -2911,8 +2911,8 @@ Op_YCbCr420_to_RRGGBBaa::state_after_conversion(ColorState input_state, std::shared_ptr Op_YCbCr420_to_RRGGBBaa::convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options) + const ColorState& target_state, + const ColorConversionOptions& options) { int width = input->get_width(); int height = input->get_height(); @@ -3002,7 +3002,7 @@ struct Node { Node() = default; - Node(int prev, const std::shared_ptr& _op, ColorStateWithCost state) + Node(int prev, const std::shared_ptr& _op, const ColorStateWithCost& state) { prev_processed_idx = prev; op = _op; @@ -3015,9 +3015,9 @@ struct Node }; -bool ColorConversionPipeline::construct_pipeline(ColorState input_state, - ColorState target_state, - ColorConversionOptions options) +bool ColorConversionPipeline::construct_pipeline(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options) { m_operations.clear(); @@ -3227,7 +3227,7 @@ std::shared_ptr ColorConversionPipeline::convert_image(const std std::shared_ptr heif::convert_colorspace(const std::shared_ptr& input, heif_colorspace target_colorspace, heif_chroma target_chroma, - std::shared_ptr target_profile, + const std::shared_ptr& target_profile, int output_bpp) { // --- check that input image is valid diff --git a/libheif/heif_colorconversion.h b/libheif/heif_colorconversion.h index ff714e8cc6..498c6d579a 100644 --- a/libheif/heif_colorconversion.h +++ b/libheif/heif_colorconversion.h @@ -105,23 +105,23 @@ namespace heif { // provide a range of conversion options. // Also returns the cost for this conversion. virtual std::vector - state_after_conversion(ColorState input_state, - ColorState target_state, - ColorConversionOptions options = ColorConversionOptions()) = 0; + state_after_conversion(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options = ColorConversionOptions()) = 0; virtual std::shared_ptr convert_colorspace(const std::shared_ptr& input, - ColorState target_state, - ColorConversionOptions options = ColorConversionOptions()) = 0; + const ColorState& target_state, + const ColorConversionOptions& options = ColorConversionOptions()) = 0; }; class ColorConversionPipeline { public: - bool construct_pipeline(ColorState input_state, - ColorState target_state, - ColorConversionOptions options = ColorConversionOptions()); + bool construct_pipeline(const ColorState& input_state, + const ColorState& target_state, + const ColorConversionOptions& options = ColorConversionOptions()); std::shared_ptr convert_image(const std::shared_ptr& input); @@ -138,6 +138,6 @@ namespace heif { std::shared_ptr convert_colorspace(const std::shared_ptr& input, heif_colorspace colorspace, heif_chroma chroma, - std::shared_ptr target_profile, + const std::shared_ptr& target_profile, int output_bpp = 0); } diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index 1d0ba6a5d8..19568b6966 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -405,7 +405,7 @@ HeifContext::~HeifContext() } } -Error HeifContext::read(std::shared_ptr reader) +Error HeifContext::read(const std::shared_ptr& reader) { m_heif_file = std::make_shared(); Error err = m_heif_file->read(reader); @@ -506,11 +506,11 @@ static bool item_type_is_image(const std::string& item_type) } -void HeifContext::remove_top_level_image(std::shared_ptr image) +void HeifContext::remove_top_level_image(const std::shared_ptr& image) { std::vector> new_list; - for (auto img : m_top_level_images) { + for (const auto& img : m_top_level_images) { if (img != image) { new_list.push_back(img); } @@ -1554,7 +1554,7 @@ Error HeifContext::decode_full_grid_image(heif_item_id ID, Error HeifContext::decode_and_paste_tile_image(heif_item_id tileID, - std::shared_ptr img, + const std::shared_ptr& img, int x0, int y0) const { std::shared_ptr tile_img; @@ -1756,7 +1756,7 @@ Error HeifContext::decode_overlay_image(heif_item_id ID, static std::shared_ptr -create_alpha_image_from_image_alpha_channel(const std::shared_ptr image) +create_alpha_image_from_image_alpha_channel(const std::shared_ptr& image) { // --- generate alpha image @@ -1872,7 +1872,7 @@ void HeifContext::Image::set_preencoded_hevc_image(const std::vector& d } -Error HeifContext::encode_image(std::shared_ptr pixel_image, +Error HeifContext::encode_image(const std::shared_ptr& pixel_image, struct heif_encoder* encoder, const struct heif_encoding_options* options, enum heif_image_input_class input_class, @@ -1913,7 +1913,7 @@ Error HeifContext::encode_image(std::shared_ptr pixel_image, } -Error HeifContext::encode_image_as_hevc(std::shared_ptr image, +Error HeifContext::encode_image_as_hevc(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options* options, enum heif_image_input_class input_class, @@ -1939,25 +1939,28 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, encoder->plugin->query_input_colorspace(&colorspace, &chroma); } + std::shared_ptr src_image; if (colorspace != image->get_colorspace() || chroma != image->get_chroma_format()) { // @TODO: use color profile when converting - image = convert_colorspace(image, colorspace, chroma, nclx_profile); - if (!image) { + src_image = convert_colorspace(image, colorspace, chroma, nclx_profile); + if (!src_image) { return Error(heif_error_Unsupported_feature, heif_suberror_Unsupported_color_conversion); } + } else { + src_image = image; } - out_image->set_size(image->get_width(heif_channel_Y), - image->get_height(heif_channel_Y)); + out_image->set_size(src_image->get_width(heif_channel_Y), + src_image->get_height(heif_channel_Y)); m_heif_file->add_hvcC_property(image_id); heif_image c_api_image; - c_api_image.image = image; + c_api_image.image = src_image; struct heif_error err = encoder->plugin->encode_image(encoder->encoder, &c_api_image, input_class); if (err.code) { @@ -2025,7 +2028,7 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, if (!is_integer_multiple_of_chroma_size(out_image->get_width(), out_image->get_height(), - image->get_chroma_format())) { + src_image->get_chroma_format())) { out_image->mark_not_miaf_compatible(); } } @@ -2039,14 +2042,14 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, ImageGrid grid; grid.set_num_tiles(1, 1); - grid.set_output_size(image->get_width(heif_channel_Y), image->get_height(heif_channel_Y)); // TODO: using out_image->get_width/height() would be shorter. + grid.set_output_size(src_image->get_width(heif_channel_Y), src_image->get_height(heif_channel_Y)); // TODO: using out_image->get_width/height() would be shorter. auto grid_data = grid.write(); // MIAF 7.3.11.4.2 if (!is_integer_multiple_of_chroma_size(out_image->get_width(), out_image->get_height(), - image->get_chroma_format())) { + src_image->get_chroma_format())) { grid_image->mark_not_miaf_compatible(); } @@ -2059,8 +2062,8 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, m_heif_file->append_iloc_data(grid_image_id, grid_data, 1); m_heif_file->add_ispe_property(grid_image_id, - image->get_width(heif_channel_Y), // TODO: using out_image->get_width/height() would be shorter. - image->get_height(heif_channel_Y)); + src_image->get_width(heif_channel_Y), // TODO: using out_image->get_width/height() would be shorter. + src_image->get_height(heif_channel_Y)); m_heif_file->add_ispe_property(image_id, encoded_width, encoded_height); @@ -2083,7 +2086,7 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, // --- choose which color profile to put into 'colr' box if (input_class == heif_image_input_class_normal || input_class == heif_image_input_class_thumbnail) { - auto icc_profile = image->get_color_profile_icc(); + auto icc_profile = src_image->get_color_profile_icc(); if (icc_profile) { m_heif_file->set_color_profile(image_id, icc_profile); } @@ -2111,15 +2114,15 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, // --- write PIXI property - if (image->get_chroma_format() == heif_chroma_monochrome) { + if (src_image->get_chroma_format() == heif_chroma_monochrome) { m_heif_file->add_pixi_property(image_id, - image->get_bits_per_pixel(heif_channel_Y), 0, 0); + src_image->get_bits_per_pixel(heif_channel_Y), 0, 0); } else { m_heif_file->add_pixi_property(image_id, - image->get_bits_per_pixel(heif_channel_Y), - image->get_bits_per_pixel(heif_channel_Cb), - image->get_bits_per_pixel(heif_channel_Cr)); + src_image->get_bits_per_pixel(heif_channel_Y), + src_image->get_bits_per_pixel(heif_channel_Cb), + src_image->get_bits_per_pixel(heif_channel_Cr)); } m_top_level_images.push_back(out_image); @@ -2129,13 +2132,13 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, // --- If there is an alpha channel, add it as an additional image. // Save alpha after the color image because we need to know the final reference to the color image. - if (options->save_alpha_channel && image->has_channel(heif_channel_Alpha)) { + if (options->save_alpha_channel && src_image->has_channel(heif_channel_Alpha)) { // --- generate alpha image // TODO: can we directly code a monochrome image instead of the dummy color channels? std::shared_ptr alpha_image; - alpha_image = create_alpha_image_from_image_alpha_channel(image); + alpha_image = create_alpha_image_from_image_alpha_channel(src_image); // --- encode the alpha image @@ -2151,7 +2154,7 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, m_heif_file->add_iref_reference(heif_alpha_image->get_id(), fourcc("auxl"), {image_id}); - if (image->is_premultiplied_alpha()) { + if (src_image->is_premultiplied_alpha()) { m_heif_file->add_iref_reference(image_id, fourcc("prem"), {heif_alpha_image->get_id()}); } @@ -2165,7 +2168,7 @@ Error HeifContext::encode_image_as_hevc(std::shared_ptr image, } -Error HeifContext::encode_image_as_av1(std::shared_ptr image, +Error HeifContext::encode_image_as_av1(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options* options, enum heif_image_input_class input_class, @@ -2193,20 +2196,23 @@ Error HeifContext::encode_image_as_av1(std::shared_ptr image, encoder->plugin->query_input_colorspace(&colorspace, &chroma); } + std::shared_ptr src_image; if (colorspace != image->get_colorspace() || chroma != image->get_chroma_format()) { // @TODO: use color profile when converting - image = convert_colorspace(image, colorspace, chroma, nclx_profile); - if (!image) { + src_image = convert_colorspace(image, colorspace, chroma, nclx_profile); + if (!src_image) { return Error(heif_error_Unsupported_feature, heif_suberror_Unsupported_color_conversion); } + } else { + src_image = image; } // --- choose which color profile to put into 'colr' box if (input_class == heif_image_input_class_normal || input_class == heif_image_input_class_thumbnail) { - auto icc_profile = image->get_color_profile_icc(); + auto icc_profile = src_image->get_color_profile_icc(); if (icc_profile) { m_heif_file->set_color_profile(image_id, icc_profile); } @@ -2221,13 +2227,13 @@ Error HeifContext::encode_image_as_av1(std::shared_ptr image, // --- if there is an alpha channel, add it as an additional image - if (options->save_alpha_channel && image->has_channel(heif_channel_Alpha)) { + if (options->save_alpha_channel && src_image->has_channel(heif_channel_Alpha)) { // --- generate alpha image // TODO: can we directly code a monochrome image instead of the dummy color channels? std::shared_ptr alpha_image; - alpha_image = create_alpha_image_from_image_alpha_channel(image); + alpha_image = create_alpha_image_from_image_alpha_channel(src_image); // --- encode the alpha image @@ -2245,7 +2251,7 @@ Error HeifContext::encode_image_as_av1(std::shared_ptr image, m_heif_file->add_iref_reference(heif_alpha_image->get_id(), fourcc("auxl"), {image_id}); m_heif_file->set_auxC_property(heif_alpha_image->get_id(), "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha"); - if (image->is_premultiplied_alpha()) { + if (src_image->is_premultiplied_alpha()) { m_heif_file->add_iref_reference(image_id, fourcc("prem"), {heif_alpha_image->get_id()}); } } @@ -2254,10 +2260,10 @@ Error HeifContext::encode_image_as_av1(std::shared_ptr image, // Fill preliminary av1C in case we cannot parse the sequence_header() correctly in the code below. // TODO: maybe we can remove this later. - fill_av1C_configuration(&config, image); + fill_av1C_configuration(&config, src_image); heif_image c_api_image; - c_api_image.image = image; + c_api_image.image = src_image; encoder->plugin->encode_image(encoder->encoder, &c_api_image, input_class); @@ -2286,8 +2292,8 @@ Error HeifContext::encode_image_as_av1(std::shared_ptr image, uint32_t input_width, input_height; - input_width = image->get_width(); - input_height = image->get_height(); + input_width = src_image->get_width(); + input_height = src_image->get_height(); m_heif_file->add_ispe_property(image_id, input_width, input_height); @@ -2307,7 +2313,7 @@ Error HeifContext::encode_image_as_av1(std::shared_ptr image, if (!is_integer_multiple_of_chroma_size(out_image->get_width(), out_image->get_height(), - image->get_chroma_format())) { + src_image->get_chroma_format())) { out_image->mark_not_miaf_compatible(); } } @@ -2316,22 +2322,22 @@ Error HeifContext::encode_image_as_av1(std::shared_ptr image, // --- write PIXI property - if (image->get_chroma_format() == heif_chroma_monochrome) { + if (src_image->get_chroma_format() == heif_chroma_monochrome) { m_heif_file->add_pixi_property(image_id, - image->get_bits_per_pixel(heif_channel_Y), 0, 0); + src_image->get_bits_per_pixel(heif_channel_Y), 0, 0); } else { m_heif_file->add_pixi_property(image_id, - image->get_bits_per_pixel(heif_channel_Y), - image->get_bits_per_pixel(heif_channel_Cb), - image->get_bits_per_pixel(heif_channel_Cr)); + src_image->get_bits_per_pixel(heif_channel_Y), + src_image->get_bits_per_pixel(heif_channel_Cb), + src_image->get_bits_per_pixel(heif_channel_Cr)); } return Error::Ok; } -void HeifContext::set_primary_image(std::shared_ptr image) +void HeifContext::set_primary_image(const std::shared_ptr& image) { // update heif context @@ -2364,8 +2370,8 @@ Error HeifContext::set_primary_item(heif_item_id id) } -Error HeifContext::assign_thumbnail(std::shared_ptr master_image, - std::shared_ptr thumbnail_image) +Error HeifContext::assign_thumbnail(const std::shared_ptr& master_image, + const std::shared_ptr& thumbnail_image) { m_heif_file->add_iref_reference(thumbnail_image->get_id(), fourcc("thmb"), {master_image->get_id()}); @@ -2374,7 +2380,7 @@ Error HeifContext::assign_thumbnail(std::shared_ptr master_image, } -Error HeifContext::encode_thumbnail(std::shared_ptr image, +Error HeifContext::encode_thumbnail(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options* options, int bbox_size, @@ -2427,7 +2433,7 @@ Error HeifContext::encode_thumbnail(std::shared_ptr image, } -Error HeifContext::add_exif_metadata(std::shared_ptr master_image, const void* data, int size) +Error HeifContext::add_exif_metadata(const std::shared_ptr& master_image, const void* data, int size) { // find location of TIFF header uint32_t offset = 0; @@ -2460,13 +2466,13 @@ Error HeifContext::add_exif_metadata(std::shared_ptr master_image, const } -Error HeifContext::add_XMP_metadata(std::shared_ptr master_image, const void* data, int size) +Error HeifContext::add_XMP_metadata(const std::shared_ptr& master_image, const void* data, int size) { return add_generic_metadata(master_image, data, size, "mime", "application/rdf+xml"); } -Error HeifContext::add_generic_metadata(std::shared_ptr master_image, const void* data, int size, +Error HeifContext::add_generic_metadata(const std::shared_ptr& master_image, const void* data, int size, const char* item_type, const char* content_type) { // create an infe box describing what kind of data we are storing (this also creates a new ID) diff --git a/libheif/heif_context.h b/libheif/heif_context.h index 2b00f251db..9f369bc00e 100644 --- a/libheif/heif_context.h +++ b/libheif/heif_context.h @@ -78,7 +78,7 @@ namespace heif { m_maximum_image_height_limit = maximum_size; } - Error read(std::shared_ptr reader); + Error read(const std::shared_ptr& reader); Error read_from_file(const char* input_filename); @@ -227,7 +227,7 @@ namespace heif { } else { std::vector> auxImgs; - for (auto aux : m_aux_images) { + for (const auto& aux : m_aux_images) { if ((aux_image_filter & LIBHEIF_AUX_IMAGE_FILTER_OMIT_ALPHA) && aux->is_alpha_channel() && aux->m_implicitly_consumed_alpha) { continue; @@ -271,7 +271,7 @@ namespace heif { const std::shared_ptr& get_color_profile_icc() const { return m_color_profile_icc; } - void set_color_profile(std::shared_ptr profile) + void set_color_profile(const std::shared_ptr& profile) { auto icc = std::dynamic_pointer_cast(profile); if (icc) { @@ -351,44 +351,44 @@ namespace heif { // contain no valid data yet. void reset_to_empty_heif(); - Error encode_image(std::shared_ptr image, + Error encode_image(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options* options, enum heif_image_input_class input_class, std::shared_ptr& out_image); - Error encode_image_as_hevc(std::shared_ptr image, + Error encode_image_as_hevc(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options* options, enum heif_image_input_class input_class, std::shared_ptr& out_image); - Error encode_image_as_av1(std::shared_ptr image, + Error encode_image_as_av1(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options* options, enum heif_image_input_class input_class, std::shared_ptr& out_image); - void set_primary_image(std::shared_ptr image); + void set_primary_image(const std::shared_ptr& image); Error set_primary_item(heif_item_id id); bool is_primary_image_set() const { return m_primary_image != nullptr; } - Error assign_thumbnail(std::shared_ptr master_image, - std::shared_ptr thumbnail_image); + Error assign_thumbnail(const std::shared_ptr& master_image, + const std::shared_ptr& thumbnail_image); - Error encode_thumbnail(std::shared_ptr image, + Error encode_thumbnail(const std::shared_ptr& image, struct heif_encoder* encoder, const struct heif_encoding_options* options, int bbox_size, std::shared_ptr& out_image_handle); - Error add_exif_metadata(std::shared_ptr master_image, const void* data, int size); + Error add_exif_metadata(const std::shared_ptr& master_image, const void* data, int size); - Error add_XMP_metadata(std::shared_ptr master_image, const void* data, int size); + Error add_XMP_metadata(const std::shared_ptr& master_image, const void* data, int size); - Error add_generic_metadata(std::shared_ptr master_image, const void* data, int size, + Error add_generic_metadata(const std::shared_ptr& master_image, const void* data, int size, const char* item_type, const char* content_type); void write(StreamWriter& writer); @@ -415,14 +415,14 @@ namespace heif { Error interpret_heif_file(); - void remove_top_level_image(std::shared_ptr image); + void remove_top_level_image(const std::shared_ptr& image); Error decode_full_grid_image(heif_item_id ID, std::shared_ptr& img, const std::vector& grid_data) const; Error decode_and_paste_tile_image(heif_item_id tileID, - std::shared_ptr out_image, + const std::shared_ptr& out_image, int x0, int y0) const; Error decode_derived_image(heif_item_id ID, diff --git a/libheif/heif_cxx.h b/libheif/heif_cxx.h index 69c30a61f0..b74dbac93e 100644 --- a/libheif/heif_cxx.h +++ b/libheif/heif_cxx.h @@ -56,7 +56,7 @@ namespace heif { m_message = msg; } - std::string get_message() const + const std::string& get_message() const { return m_message; } heif_error_code get_code() const @@ -96,7 +96,7 @@ namespace heif { }; // throws Error - void read_from_file(std::string filename, const ReadingOptions& opts = ReadingOptions()); + void read_from_file(const std::string& filename, const ReadingOptions& opts = ReadingOptions()); // DEPRECATED. Use read_from_memory_without_copy() instead. // throws Error @@ -183,7 +183,7 @@ namespace heif { void write(Writer&); // throws Error - void write_to_file(std::string filename) const; + void write_to_file(const std::string& filename) const; private: std::shared_ptr m_context; @@ -445,21 +445,21 @@ namespace heif { std::vector list_parameters() const noexcept; - void set_integer_parameter(std::string parameter_name, int value); + void set_integer_parameter(const std::string& parameter_name, int value); - int get_integer_parameter(std::string parameter_name) const; + int get_integer_parameter(const std::string& parameter_name) const; - void set_boolean_parameter(std::string parameter_name, bool value); + void set_boolean_parameter(const std::string& parameter_name, bool value); - bool get_boolean_parameter(std::string parameter_name) const; + bool get_boolean_parameter(const std::string& parameter_name) const; - void set_string_parameter(std::string parameter_name, std::string value); + void set_string_parameter(const std::string& parameter_name, const std::string& value); - std::string get_string_parameter(std::string parameter_name) const; + std::string get_string_parameter(const std::string& parameter_name) const; - void set_parameter(std::string parameter_name, std::string parameter_value); + void set_parameter(const std::string& parameter_name, const std::string& parameter_value); - std::string get_parameter(std::string parameter_name) const; + std::string get_parameter(const std::string& parameter_name) const; private: Encoder(struct heif_encoder*) noexcept; @@ -483,7 +483,7 @@ namespace heif { [](heif_context* c) { heif_context_free(c); }); } - inline void Context::read_from_file(std::string filename, const ReadingOptions& /*opts*/) + inline void Context::read_from_file(const std::string& filename, const ReadingOptions& /*opts*/) { Error err = Error(heif_context_read_from_file(m_context.get(), filename.c_str(), NULL)); if (err) { @@ -638,7 +638,7 @@ namespace heif { } } - inline void Context::write_to_file(std::string filename) const + inline void Context::write_to_file(const std::string& filename) const { Error err = Error(heif_context_write_to_file(m_context.get(), filename.c_str())); if (err) { @@ -1001,6 +1001,7 @@ namespace heif { maxDescriptors); if (nDescriptors < maxDescriptors) { std::vector outDescriptors; + outDescriptors.reserve(nDescriptors); for (int i = 0; i < nDescriptors; i++) { outDescriptors.push_back(EncoderDescriptor(descriptors[i])); } @@ -1163,7 +1164,7 @@ namespace heif { } } - inline void Encoder::set_integer_parameter(std::string parameter_name, int value) + inline void Encoder::set_integer_parameter(const std::string& parameter_name, int value) { Error err = Error(heif_encoder_set_parameter_integer(m_encoder.get(), parameter_name.c_str(), value)); if (err) { @@ -1171,7 +1172,7 @@ namespace heif { } } - inline int Encoder::get_integer_parameter(std::string parameter_name) const + inline int Encoder::get_integer_parameter(const std::string& parameter_name) const { int value; Error err = Error(heif_encoder_get_parameter_integer(m_encoder.get(), parameter_name.c_str(), &value)); @@ -1181,7 +1182,7 @@ namespace heif { return value; } - inline void Encoder::set_boolean_parameter(std::string parameter_name, bool value) + inline void Encoder::set_boolean_parameter(const std::string& parameter_name, bool value) { Error err = Error(heif_encoder_set_parameter_boolean(m_encoder.get(), parameter_name.c_str(), value)); if (err) { @@ -1189,7 +1190,7 @@ namespace heif { } } - inline bool Encoder::get_boolean_parameter(std::string parameter_name) const + inline bool Encoder::get_boolean_parameter(const std::string& parameter_name) const { int value; Error err = Error(heif_encoder_get_parameter_boolean(m_encoder.get(), parameter_name.c_str(), &value)); @@ -1199,7 +1200,7 @@ namespace heif { return value; } - inline void Encoder::set_string_parameter(std::string parameter_name, std::string value) + inline void Encoder::set_string_parameter(const std::string& parameter_name, const std::string& value) { Error err = Error(heif_encoder_set_parameter_string(m_encoder.get(), parameter_name.c_str(), value.c_str())); if (err) { @@ -1207,7 +1208,7 @@ namespace heif { } } - inline std::string Encoder::get_string_parameter(std::string parameter_name) const + inline std::string Encoder::get_string_parameter(const std::string& parameter_name) const { const int max_size = 250; char value[max_size]; @@ -1219,7 +1220,7 @@ namespace heif { return value; } - inline void Encoder::set_parameter(std::string parameter_name, std::string parameter_value) + inline void Encoder::set_parameter(const std::string& parameter_name, const std::string& parameter_value) { Error err = Error(heif_encoder_set_parameter(m_encoder.get(), parameter_name.c_str(), parameter_value.c_str())); @@ -1228,7 +1229,7 @@ namespace heif { } } - inline std::string Encoder::get_parameter(std::string parameter_name) const + inline std::string Encoder::get_parameter(const std::string& parameter_name) const { const int max_size = 250; char value[max_size]; diff --git a/libheif/heif_encoder_x265.cc b/libheif/heif_encoder_x265.cc index ce9f4a5c37..3cfa296dfc 100644 --- a/libheif/heif_encoder_x265.cc +++ b/libheif/heif_encoder_x265.cc @@ -77,13 +77,13 @@ struct encoder_struct_x265 void add_param(const parameter&); - void add_param(std::string name, int value); + void add_param(const std::string& name, int value); - void add_param(std::string name, bool value); + void add_param(const std::string& name, bool value); - void add_param(std::string name, std::string value); + void add_param(const std::string& name, const std::string& value); - parameter get_param(std::string name) const; + parameter get_param(const std::string& name) const; std::string preset; std::string tune; @@ -112,7 +112,7 @@ void encoder_struct_x265::add_param(const parameter& p) } -void encoder_struct_x265::add_param(std::string name, int value) +void encoder_struct_x265::add_param(const std::string& name, int value) { parameter p; p.type = Int; @@ -121,7 +121,7 @@ void encoder_struct_x265::add_param(std::string name, int value) add_param(p); } -void encoder_struct_x265::add_param(std::string name, bool value) +void encoder_struct_x265::add_param(const std::string& name, bool value) { parameter p; p.type = Bool; @@ -130,7 +130,7 @@ void encoder_struct_x265::add_param(std::string name, bool value) add_param(p); } -void encoder_struct_x265::add_param(std::string name, std::string value) +void encoder_struct_x265::add_param(const std::string& name, const std::string& value) { parameter p; p.type = String; @@ -140,7 +140,7 @@ void encoder_struct_x265::add_param(std::string name, std::string value) } -parameter encoder_struct_x265::get_param(std::string name) const +parameter encoder_struct_x265::get_param(const std::string& name) const { for (size_t i = 0; i < parameters.size(); i++) { if (parameters[i].name == name) { @@ -188,7 +188,7 @@ static const char* x265_plugin_name() strcpy(plugin_name, "x265 HEVC encoder"); const char* x265_version = (x265_version_str != nullptr ? x265_version_str : "null"); - + if (strlen(x265_version) + strlen(plugin_name) + 4 < MAX_PLUGIN_NAME_LENGTH) { strcat(plugin_name, " ("); strcat(plugin_name, x265_version); @@ -772,6 +772,8 @@ static struct heif_error x265_encode_image(void* encoder_raw, const struct heif_ assert(heif_image_get_width(image, heif_channel_Cr)==w); assert(heif_image_get_height(image, heif_channel_Cb)==h); assert(heif_image_get_height(image, heif_channel_Cr)==h); + (void) w; + (void) h; } api->param_parse(param, "info", "0"); diff --git a/libheif/heif_file.cc b/libheif/heif_file.cc index 0a685ad279..1bb60630b5 100644 --- a/libheif/heif_file.cc +++ b/libheif/heif_file.cc @@ -90,7 +90,7 @@ Error HeifFile::read_from_memory(const void* data, size_t size, bool copy) } -Error HeifFile::read(std::shared_ptr reader) +Error HeifFile::read(const std::shared_ptr& reader) { m_input_stream = reader; @@ -837,7 +837,7 @@ void HeifFile::set_primary_item_id(heif_item_id id) } void HeifFile::add_iref_reference(uint32_t type, heif_item_id from, - std::vector to) + const std::vector& to) { if (!m_iref_box) { m_iref_box = std::make_shared(); @@ -847,7 +847,7 @@ void HeifFile::add_iref_reference(uint32_t type, heif_item_id from, m_iref_box->add_reference(type, from, to); } -void HeifFile::set_auxC_property(heif_item_id id, std::string type) +void HeifFile::set_auxC_property(heif_item_id id, const std::string& type) { auto auxC = std::make_shared(); auxC->set_aux_type(type); @@ -857,7 +857,7 @@ void HeifFile::set_auxC_property(heif_item_id id, std::string type) m_ipma_box->add_property_for_item_ID(id, Box_ipma::PropertyAssociation{true, uint16_t(index + 1)}); } -void HeifFile::set_color_profile(heif_item_id id, const std::shared_ptr profile) +void HeifFile::set_color_profile(heif_item_id id, const std::shared_ptr& profile) { auto colr = std::make_shared(); colr->set_color_profile(profile); @@ -868,7 +868,7 @@ void HeifFile::set_color_profile(heif_item_id id, const std::shared_ptr reader); + Error read(const std::shared_ptr& reader); Error read_from_file(const char* input_filename); @@ -146,14 +146,14 @@ namespace heif { void set_primary_item_id(heif_item_id id); void add_iref_reference(heif_item_id from, uint32_t type, - std::vector to); + const std::vector& to); - void set_auxC_property(heif_item_id id, std::string type); + void set_auxC_property(heif_item_id id, const std::string& type); - void set_color_profile(heif_item_id id, const std::shared_ptr profile); + void set_color_profile(heif_item_id id, const std::shared_ptr& profile); // TODO: the hdlr box is probably not the right place for this. Into which box should we write comments? - void set_hdlr_library_info(std::string encoder_plugin_version); + void set_hdlr_library_info(const std::string& encoder_plugin_version); #if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER) static std::wstring convert_utf8_path_to_utf16(std::string pathutf8); diff --git a/libheif/heif_image.h b/libheif/heif_image.h index e0febb59dd..dd917d4461 100644 --- a/libheif/heif_image.h +++ b/libheif/heif_image.h @@ -121,13 +121,13 @@ namespace heif { Error scale_nearest_neighbor(std::shared_ptr& output, int width, int height) const; - void set_color_profile_nclx(std::shared_ptr profile) { m_color_profile_nclx = profile; } + void set_color_profile_nclx(const std::shared_ptr& profile) { m_color_profile_nclx = profile; } - std::shared_ptr get_color_profile_nclx() const { return m_color_profile_nclx; } + const std::shared_ptr& get_color_profile_nclx() const { return m_color_profile_nclx; } - void set_color_profile_icc(std::shared_ptr profile) { m_color_profile_icc = profile; } + void set_color_profile_icc(const std::shared_ptr& profile) { m_color_profile_icc = profile; } - std::shared_ptr get_color_profile_icc() const { return m_color_profile_icc; } + const std::shared_ptr& get_color_profile_icc() const { return m_color_profile_icc; } void debug_dump() const; From 6579dff8cb007dd3ff67d32b15e116663f84319d Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 21 Feb 2022 10:19:09 +0100 Subject: [PATCH 0031/3088] Use "std::lround" instead of "lround" to prevent promotion to double. Found by clang-tidy. --- libheif/heif_colorconversion.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc index 579f299e9c..ce492ca70e 100644 --- a/libheif/heif_colorconversion.cc +++ b/libheif/heif_colorconversion.cc @@ -856,10 +856,10 @@ Op_YCbCr420_to_RGB24::convert_colorspace(const std::shared_ptrget_colour_primaries()); } - int r_cr = static_cast(lround(256 * coeffs.r_cr)); - int g_cr = static_cast(lround(256 * coeffs.g_cr)); - int g_cb = static_cast(lround(256 * coeffs.g_cb)); - int b_cb = static_cast(lround(256 * coeffs.b_cb)); + int r_cr = static_cast(std::lround(256 * coeffs.r_cr)); + int g_cr = static_cast(std::lround(256 * coeffs.g_cr)); + int g_cb = static_cast(std::lround(256 * coeffs.g_cb)); + int b_cb = static_cast(std::lround(256 * coeffs.b_cb)); const uint8_t* in_y, * in_cb, * in_cr; int in_y_stride = 0, in_cb_stride = 0, in_cr_stride = 0; @@ -977,10 +977,10 @@ Op_YCbCr420_to_RGB32::convert_colorspace(const std::shared_ptrget_colour_primaries()); } - int r_cr = static_cast(lround(256 * coeffs.r_cr)); - int g_cr = static_cast(lround(256 * coeffs.g_cr)); - int g_cb = static_cast(lround(256 * coeffs.g_cb)); - int b_cb = static_cast(lround(256 * coeffs.b_cb)); + int r_cr = static_cast(std::lround(256 * coeffs.r_cr)); + int g_cr = static_cast(std::lround(256 * coeffs.g_cr)); + int g_cb = static_cast(std::lround(256 * coeffs.g_cb)); + int b_cb = static_cast(std::lround(256 * coeffs.b_cb)); const bool with_alpha = input->has_channel(heif_channel_Alpha); From 335d004985d13c5a0b7108a535a0c7f3ab031874 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 21 Feb 2022 10:51:09 +0100 Subject: [PATCH 0032/3088] Use "= default" for default constructors/destructors and add "override" where missing. --- examples/encoder.h | 3 +-- examples/encoder_png.cc | 4 +--- examples/encoder_y4m.cc | 4 +--- libheif/bitstream.h | 5 ++--- libheif/box.cc | 4 +--- libheif/box.h | 14 +++++--------- libheif/error.cc | 6 +----- libheif/error.h | 7 +++---- libheif/heif_context.cc | 4 +--- libheif/heif_cxx.h | 12 ++++-------- libheif/heif_file.cc | 10 ++-------- libheif/logging.h | 5 ++--- 12 files changed, 24 insertions(+), 54 deletions(-) diff --git a/examples/encoder.h b/examples/encoder.h index e1afd35782..5dece2f9db 100644 --- a/examples/encoder.h +++ b/examples/encoder.h @@ -34,8 +34,7 @@ class Encoder { public: - virtual ~Encoder() - {} + virtual ~Encoder() = default; virtual heif_colorspace colorspace(bool has_alpha) const = 0; diff --git a/examples/encoder_png.cc b/examples/encoder_png.cc index d5158dbf4a..c999722ec0 100644 --- a/examples/encoder_png.cc +++ b/examples/encoder_png.cc @@ -32,9 +32,7 @@ #include "encoder_png.h" -PngEncoder::PngEncoder() -{} - +PngEncoder::PngEncoder() = default; bool PngEncoder::Encode(const struct heif_image_handle* handle, const struct heif_image* image, const std::string& filename) diff --git a/examples/encoder_y4m.cc b/examples/encoder_y4m.cc index a2340072ad..7ae18861b4 100644 --- a/examples/encoder_y4m.cc +++ b/examples/encoder_y4m.cc @@ -30,9 +30,7 @@ #include -Y4MEncoder::Y4MEncoder() -{ -} +Y4MEncoder::Y4MEncoder() = default; void Y4MEncoder::UpdateDecodingOptions(const struct heif_image_handle* handle, diff --git a/libheif/bitstream.h b/libheif/bitstream.h index 48c4c5a89c..8d62c872e8 100644 --- a/libheif/bitstream.h +++ b/libheif/bitstream.h @@ -43,8 +43,7 @@ namespace heif { class StreamReader { public: - virtual ~StreamReader() - {} + virtual ~StreamReader() = default; virtual int64_t get_position() const = 0; @@ -94,7 +93,7 @@ namespace heif { public: StreamReader_memory(const uint8_t* data, int64_t size, bool copy); - ~StreamReader_memory(); + ~StreamReader_memory() override; int64_t get_position() const override; diff --git a/libheif/box.cc b/libheif/box.cc index a44120271c..8cae4fdad4 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -144,9 +144,7 @@ static std::string to_fourcc(uint32_t code) } -heif::BoxHeader::BoxHeader() -{ -} +heif::BoxHeader::BoxHeader() = default; std::vector heif::BoxHeader::get_type() const diff --git a/libheif/box.h b/libheif/box.h index f1c8211601..6f418a93ff 100644 --- a/libheif/box.h +++ b/libheif/box.h @@ -64,8 +64,7 @@ namespace heif { class Fraction { public: - Fraction() - {} + Fraction() = default; Fraction(int32_t num, int32_t den); @@ -107,8 +106,7 @@ namespace heif { public: BoxHeader(); - virtual ~BoxHeader() - {} + virtual ~BoxHeader() = default; constexpr static uint64_t size_until_end_of_file = 0; @@ -181,8 +179,7 @@ namespace heif { class Box : public BoxHeader { public: - Box() - {} + Box() = default; Box(const BoxHeader& hdr) : BoxHeader(hdr) {} @@ -197,7 +194,7 @@ namespace heif { void derive_box_version_recursive(); - virtual std::string dump(Indent&) const; + std::string dump(Indent&) const override; std::shared_ptr get_child_box(uint32_t short_type) const; @@ -1086,8 +1083,7 @@ namespace heif { class color_profile { public: - virtual ~color_profile() - {} + virtual ~color_profile() = default; virtual uint32_t get_type() const = 0; diff --git a/libheif/error.cc b/libheif/error.cc index 6aabdb5fa9..cd6e13a37b 100644 --- a/libheif/error.cc +++ b/libheif/error.cc @@ -27,11 +27,7 @@ const char heif::Error::kSuccess[] = "Success"; const char* cUnknownError = "Unknown error"; -heif::Error::Error() - : error_code(heif_error_Ok), - sub_error_code(heif_suberror_Unspecified) -{ -} +heif::Error::Error() = default; heif::Error::Error(heif_error_code c, diff --git a/libheif/error.h b/libheif/error.h index 0a2f67949e..f4e8bb841a 100644 --- a/libheif/error.h +++ b/libheif/error.h @@ -48,8 +48,7 @@ namespace heif { class ErrorBuffer { public: - ErrorBuffer() - {} + ErrorBuffer() = default; void set_success() { @@ -77,8 +76,8 @@ namespace heif { class Error { public: - enum heif_error_code error_code; - enum heif_suberror_code sub_error_code; + enum heif_error_code error_code = heif_error_Ok; + enum heif_suberror_code sub_error_code = heif_suberror_Unspecified; std::string message; Error(); diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index 19568b6966..7f57eaa0d3 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -933,9 +933,7 @@ HeifContext::Image::Image(HeifContext* context, heif_item_id id) memset(&m_depth_representation_info, 0, sizeof(m_depth_representation_info)); } -HeifContext::Image::~Image() -{ -} +HeifContext::Image::~Image() = default; bool HeifContext::is_image(heif_item_id ID) const { diff --git a/libheif/heif_cxx.h b/libheif/heif_cxx.h index b74dbac93e..269541f7f3 100644 --- a/libheif/heif_cxx.h +++ b/libheif/heif_cxx.h @@ -108,8 +108,7 @@ namespace heif { class Reader { public: - virtual ~Reader() - {} + virtual ~Reader() = default; virtual int64_t get_position() const = 0; @@ -173,8 +172,7 @@ namespace heif { class Writer { public: - virtual ~Writer() - {} + virtual ~Writer() = default; virtual heif_error write(const void* data, size_t size) = 0; }; @@ -200,8 +198,7 @@ namespace heif { class ImageHandle { public: - ImageHandle() - {} + ImageHandle() = default; ImageHandle(heif_image_handle* handle); @@ -308,8 +305,7 @@ namespace heif { class Image { public: - Image() - {} + Image() = default; Image(heif_image* image); diff --git a/libheif/heif_file.cc b/libheif/heif_file.cc index 1bb60630b5..dce316afb4 100644 --- a/libheif/heif_file.cc +++ b/libheif/heif_file.cc @@ -42,15 +42,9 @@ using namespace heif; #define STRICT_PARSING false -HeifFile::HeifFile() -{ -} - - -HeifFile::~HeifFile() -{ -} +HeifFile::HeifFile() = default; +HeifFile::~HeifFile() = default; std::vector HeifFile::get_item_IDs() const { diff --git a/libheif/logging.h b/libheif/logging.h index b370763f63..4659ce09b2 100644 --- a/libheif/logging.h +++ b/libheif/logging.h @@ -40,8 +40,7 @@ namespace heif { class Indent { public: - Indent() : m_indent(0) - {} + Indent() = default; int get_indent() const { return m_indent; } @@ -56,7 +55,7 @@ namespace heif { } private: - int m_indent; + int m_indent = 0; }; From deb66b21ad266b699f05b4fd88f22b2853908b0c Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 21 Feb 2022 09:11:21 +0100 Subject: [PATCH 0033/3088] CI: Add job to run clang-tidy. --- .clang-tidy | 13 +++++++++++++ .github/workflows/clang.yml | 31 +++++++++++++++++++++++++++++++ scripts/run-ci.sh | 5 ++++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000000..7cb3c16679 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,13 @@ +--- +Checks: > + -clang-analyzer-security.insecureAPI.strcat, + -clang-analyzer-security.insecureAPI.strcpy, + modernize-shrink-to-fit, + modernize-use-default-member-init, + modernize-use-equals-default, + modernize-use-equals-delete, + modernize-use-override, + performance-* +HeaderFilterRegex: .* +WarningsAsErrors: '*' +... diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 8781a26a72..02ab82853d 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -37,3 +37,34 @@ jobs: CXX: clang++ run: | ./scripts/run-ci.sh + + tidy: + env: + WITH_GRAPHICS: 1 + WITH_X265: 1 + WITH_AOM: 1 + WITH_DAV1D: 1 + WITH_RAV1E: 1 + WITH_LIBDE265: 1 + CMAKE: 1 + CLANG_TIDY: 1 + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + + - name: Install dependencies + run: | + ./scripts/install-ci-linux.sh + sudo apt install clang-tidy-12 + + - name: Prepare CI + run: | + ./scripts/prepare-ci.sh + + - name: Run tests + run: | + ./scripts/run-ci.sh + + - name: Run clang-tidy + run: | + run-clang-tidy-12 -j$(nproc) diff --git a/scripts/run-ci.sh b/scripts/run-ci.sh index 706e432d02..49211c2296 100755 --- a/scripts/run-ci.sh +++ b/scripts/run-ci.sh @@ -133,6 +133,9 @@ if [ ! -z "$CMAKE" ]; then if [ "$WITH_RAV1E" = "1" ]; then CMAKE_OPTIONS="$CMAKE_OPTIONS -DUSE_LOCAL_RAV1E=1" fi + if [ "$CLANG_TIDY" = "1" ]; then + CMAKE_OPTIONS="$CMAKE_OPTIONS -DCMAKE_EXPORT_COMPILE_COMMANDS=ON" + fi cmake . $CMAKE_OPTIONS fi @@ -141,7 +144,7 @@ if [ ! -z "$FUZZER" ] && [ "$CURRENT_OS" = "linux" ]; then export ASAN_SYMBOLIZER="$BUILD_ROOT/clang/bin/llvm-symbolizer" fi -if [ -z "$EMSCRIPTEN_VERSION" ] && [ -z "$CHECK_LICENSES" ] && [ -z "$TARBALL" ]; then +if [ -z "$EMSCRIPTEN_VERSION" ] && [ -z "$CHECK_LICENSES" ] && [ -z "$TARBALL" ] && [ -z "$CLANG_TIDY" ]; then echo "Building libheif ..." make -j $(nproc) if [ "$CURRENT_OS" = "linux" ] && [ -z "$CMAKE" ] && [ -z "$MINGW" ] && [ -z "$FUZZER" ]; then From 518d1113863b8633112174c1d19615bb7f2f32c3 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 21 Feb 2022 09:21:10 +0100 Subject: [PATCH 0034/3088] clang-tidy: Ignore warning about excessive padding. Can't be changed as the API is already released. --- libheif/heif_plugin.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libheif/heif_plugin.h b/libheif/heif_plugin.h index d1960fb12a..609c426c03 100644 --- a/libheif/heif_plugin.h +++ b/libheif/heif_plugin.h @@ -229,6 +229,7 @@ struct heif_encoder_plugin // For use only by the encoder plugins. // Application programs should use the access functions. +// NOLINTNEXTLINE(clang-analyzer-optin.performance.Padding) struct heif_encoder_parameter { int version; // current version: 2 From f43b3fc00862a9f3c2566d5adfc9d4866ad8e077 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 21 Feb 2022 09:24:01 +0100 Subject: [PATCH 0035/3088] clang-tidy: Ignore warning about division by zero. In the release build, the assertions in "chroma_[hv]_subsampling" are not triggered, so the functions return "0". --- libheif/heif_image.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libheif/heif_image.cc b/libheif/heif_image.cc index 1dc0659c86..338933d671 100644 --- a/libheif/heif_image.cc +++ b/libheif/heif_image.cc @@ -237,7 +237,9 @@ void heif::get_subsampled_size(int width, int height, uint8_t chromaSubH = chroma_h_subsampling(chroma); uint8_t chromaSubV = chroma_v_subsampling(chroma); + // NOLINTNEXTLINE(clang-analyzer-core.DivideZero) *subsampled_width = (width + chromaSubH - 1) / chromaSubH; + // NOLINTNEXTLINE(clang-analyzer-core.DivideZero) *subsampled_height = (height + chromaSubV - 1) / chromaSubV; } else { From 85599ec2c7bd81ceba38f520aebf922af6595b20 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 21 Feb 2022 09:49:55 +0100 Subject: [PATCH 0036/3088] clang-tidy: Ignore warning about uninitialized value. "get_id_of_non_virtual_child_image" returns an error if the ID is not found, so this is a false-positive of clang-tidy. --- libheif/heif_context.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index 7f57eaa0d3..6916b18bda 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -987,6 +987,7 @@ int HeifContext::Image::get_luma_bits_per_pixel() const return -1; } + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) return m_heif_context->m_heif_file->get_luma_bits_per_pixel_from_configuration(id); } @@ -999,6 +1000,7 @@ int HeifContext::Image::get_chroma_bits_per_pixel() const return -1; } + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) return m_heif_context->m_heif_file->get_chroma_bits_per_pixel_from_configuration(id); } From dfa3b4aa07ba94a9cf6f21d10926dcb5def53a42 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 17:02:21 +0100 Subject: [PATCH 0037/3088] heif_image may now hold a list of decoding warnings --- libheif/heif.cc | 19 +++++++++++++++++++ libheif/heif.h | 12 ++++++++++++ libheif/heif_image.h | 6 ++++++ 3 files changed, 37 insertions(+) diff --git a/libheif/heif.cc b/libheif/heif.cc index 082d1e9475..20981c8061 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -945,6 +945,25 @@ struct heif_error heif_image_create(int width, int height, return err; } +int heif_image_get_decoding_warnings(struct heif_image* image, + int first_warning_idx, + struct heif_error* out_warnings, + int max_output_buffer_entries) +{ + if (max_output_buffer_entries == 0) { + return (int) image->image->get_warnings().size(); + } + else { + const auto& warnings = image->image->get_warnings(); + int n; + for (n = 0; n + first_warning_idx < (int) warnings.size(); n++) { + out_warnings[n] = warnings[n + first_warning_idx].error_struct(image->image.get()); + } + return n; + } +} + + void heif_image_release(const struct heif_image* img) { delete img; diff --git a/libheif/heif.h b/libheif/heif.h index 8f6c751c5a..24466c0ca8 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -1043,6 +1043,18 @@ struct heif_error heif_image_set_nclx_color_profile(struct heif_image* image, //LIBHEIF_API //void heif_image_remove_color_profile(struct heif_image* image); +// Fills the image decoding warnings into the provided 'out_warnings' array. +// The size of the array has to be provided in max_output_buffer_entries. +// If max_output_buffer_entries==0, the number of decoder warnings is returned. +// The function fills the warnings into the provided buffer, starting with 'first_warning_idx'. +// It returns the number of warnings filled into the buffer. +// Note: you can iterate through all warnings by using 'max_output_buffer_entries=1' and iterate 'first_warning_idx'. +LIBHEIF_API +int heif_image_get_decoding_warnings(struct heif_image* image, + int first_warning_idx, + struct heif_error* out_warnings, + int max_output_buffer_entries); + // Release heif_image. LIBHEIF_API void heif_image_release(const struct heif_image*); diff --git a/libheif/heif_image.h b/libheif/heif_image.h index dd917d4461..e3942c515c 100644 --- a/libheif/heif_image.h +++ b/libheif/heif_image.h @@ -133,6 +133,10 @@ namespace heif { bool extend_padding_to_size(int width, int height); + void add_warning(Error warning) { m_warnings.emplace_back(std::move(warning)); } + + const std::vector& get_warnings() const { return m_warnings; } + private: struct ImagePlane { @@ -162,6 +166,8 @@ namespace heif { std::shared_ptr m_color_profile_icc; std::map m_planes; + + std::vector m_warnings; }; } From af26f6d52598347b348a87f4dfb476c48ae1ac81 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 17:44:10 +0100 Subject: [PATCH 0038/3088] add include for std::move() --- libheif/heif_image.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libheif/heif_image.h b/libheif/heif_image.h index e3942c515c..03e100fe80 100644 --- a/libheif/heif_image.h +++ b/libheif/heif_image.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace heif { From ffdac1ed91e74ecd67e53622070e775d164e7d3a Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 17:51:32 +0100 Subject: [PATCH 0039/3088] API to safely set nclx color primaries --- libheif/error.cc | 2 ++ libheif/heif.cc | 35 +++++++++++++++++++++++++++++++++++ libheif/heif.h | 5 +++++ 3 files changed, 42 insertions(+) diff --git a/libheif/error.cc b/libheif/error.cc index cd6e13a37b..ee7100f082 100644 --- a/libheif/error.cc +++ b/libheif/error.cc @@ -145,6 +145,8 @@ const char* heif::Error::get_error_string(heif_suberror_code err) return "Invalid pixi box"; case heif_suberror_Wrong_tile_image_pixel_depth: return "Wrong tile image pixel depth"; + case heif_suberror_Unknown_NCLX_color_primaries: + return "Unknown NCLX color primaries"; // --- Memory_allocation_error --- diff --git a/libheif/heif.cc b/libheif/heif.cc index 20981c8061..1e57b31826 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -1332,6 +1332,41 @@ size_t heif_image_handle_get_raw_color_profile_size(const struct heif_image_hand } +static const std::set known_color_primaries{ + heif_color_primaries_ITU_R_BT_709_5, + heif_color_primaries_unspecified, + heif_color_primaries_ITU_R_BT_470_6_System_M, + heif_color_primaries_ITU_R_BT_470_6_System_B_G, + heif_color_primaries_ITU_R_BT_601_6, + heif_color_primaries_SMPTE_240M, + heif_color_primaries_generic_film, + heif_color_primaries_ITU_R_BT_2020_2_and_2100_0, + heif_color_primaries_SMPTE_ST_428_1, + heif_color_primaries_SMPTE_RP_431_2, + heif_color_primaries_SMPTE_EG_432_1, + heif_color_primaries_EBU_Tech_3213_E, +}; + +struct heif_error heif_color_profile_nclx_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t n) +{ + if (n < std::numeric_limits::type>::min() || + n > std::numeric_limits::type>::max()) { + return Error(heif_error_Invalid_input, heif_suberror_Unknown_NCLX_color_primaries).error_struct(nullptr); + } + + auto p = static_cast(n); + if (known_color_primaries.find(p) != known_color_primaries.end()) { + nclx->color_primaries = p; + } + else { + nclx->color_primaries = heif_color_primaries_unspecified; + return Error(heif_error_Invalid_input, heif_suberror_Unknown_NCLX_color_primaries).error_struct(nullptr); + } + + return Error::Ok.error_struct(nullptr); +} + + struct heif_error heif_image_handle_get_nclx_color_profile(const struct heif_image_handle* handle, struct heif_color_profile_nclx** out_data) { diff --git a/libheif/heif.h b/libheif/heif.h index 24466c0ca8..4b49fe0dd0 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -207,6 +207,8 @@ enum heif_suberror_code heif_suberror_Wrong_tile_image_pixel_depth = 132, + heif_suberror_Unknown_NCLX_color_primaries = 133, + // --- Memory_allocation_error --- @@ -803,6 +805,9 @@ struct heif_color_profile_nclx float color_primary_white_x, color_primary_white_y; }; +LIBHEIF_API +struct heif_error heif_color_profile_nclx_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t primaries); + // Returns 'heif_error_Color_profile_does_not_exist' when there is no NCLX profile. // TODO: This function does currently not return an NCLX profile if it is stored in the image bitstream. // Only NCLX profiles stored as colr boxes are returned. This may change in the future. From 73e8ee7143b1265db2ec354294f9ee86dd7d97cf Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 17:55:33 +0100 Subject: [PATCH 0040/3088] rename API for consistency and add missing includes --- libheif/heif.cc | 4 +++- libheif/heif.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libheif/heif.cc b/libheif/heif.cc index 1e57b31826..434d53689e 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -30,6 +30,8 @@ #include "heif_plugin_registry.h" #include "error.h" #include "bitstream.h" +#include +#include #if defined(__EMSCRIPTEN__) #include "heif_emscripten.h" @@ -1347,7 +1349,7 @@ static const std::set known_color_primaries{ heif_color_primaries_EBU_Tech_3213_E, }; -struct heif_error heif_color_profile_nclx_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t n) +struct heif_error heif_nclx_color_profile_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t n) { if (n < std::numeric_limits::type>::min() || n > std::numeric_limits::type>::max()) { diff --git a/libheif/heif.h b/libheif/heif.h index 4b49fe0dd0..728434de44 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -806,7 +806,7 @@ struct heif_color_profile_nclx }; LIBHEIF_API -struct heif_error heif_color_profile_nclx_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t primaries); +struct heif_error heif_nclx_color_profile_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t primaries); // Returns 'heif_error_Color_profile_does_not_exist' when there is no NCLX profile. // TODO: This function does currently not return an NCLX profile if it is stored in the image bitstream. From 713c8f1bd499e205ec915cdbb90269c5b0ce7e25 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 18:07:29 +0100 Subject: [PATCH 0041/3088] API to safely set nclx transfer characteristics and matrix coefficients --- libheif/error.cc | 4 +++ libheif/heif.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++---- libheif/heif.h | 12 ++++++- 3 files changed, 99 insertions(+), 7 deletions(-) diff --git a/libheif/error.cc b/libheif/error.cc index ee7100f082..19224e92ee 100644 --- a/libheif/error.cc +++ b/libheif/error.cc @@ -147,6 +147,10 @@ const char* heif::Error::get_error_string(heif_suberror_code err) return "Wrong tile image pixel depth"; case heif_suberror_Unknown_NCLX_color_primaries: return "Unknown NCLX color primaries"; + case heif_suberror_Unknown_NCLX_transfer_characteristics: + return "Unknown NCLX transfer characteristics"; + case heif_suberror_Unknown_NCLX_matrix_coefficients: + return "Unknown NCLX matrix coefficients"; // --- Memory_allocation_error --- diff --git a/libheif/heif.cc b/libheif/heif.cc index 434d53689e..6e765e4a8a 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -1349,16 +1349,16 @@ static const std::set known_color_primaries{ heif_color_primaries_EBU_Tech_3213_E, }; -struct heif_error heif_nclx_color_profile_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t n) +struct heif_error heif_nclx_color_profile_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t cp) { - if (n < std::numeric_limits::type>::min() || - n > std::numeric_limits::type>::max()) { + if (cp < std::numeric_limits::type>::min() || + cp > std::numeric_limits::type>::max()) { return Error(heif_error_Invalid_input, heif_suberror_Unknown_NCLX_color_primaries).error_struct(nullptr); } - auto p = static_cast(n); - if (known_color_primaries.find(p) != known_color_primaries.end()) { - nclx->color_primaries = p; + auto n = static_cast(cp); + if (known_color_primaries.find(n) != known_color_primaries.end()) { + nclx->color_primaries = n; } else { nclx->color_primaries = heif_color_primaries_unspecified; @@ -1369,6 +1369,84 @@ struct heif_error heif_nclx_color_profile_set_color_primaries(heif_color_profile } +static const std::set known_transfer_characteristics{ + heif_transfer_characteristic_ITU_R_BT_709_5, + heif_transfer_characteristic_unspecified, + heif_transfer_characteristic_ITU_R_BT_470_6_System_M, + heif_transfer_characteristic_ITU_R_BT_470_6_System_B_G, + heif_transfer_characteristic_ITU_R_BT_601_6, + heif_transfer_characteristic_SMPTE_240M, + heif_transfer_characteristic_linear, + heif_transfer_characteristic_logarithmic_100, + heif_transfer_characteristic_logarithmic_100_sqrt10, + heif_transfer_characteristic_IEC_61966_2_4, + heif_transfer_characteristic_ITU_R_BT_1361, + heif_transfer_characteristic_IEC_61966_2_1, + heif_transfer_characteristic_ITU_R_BT_2020_2_10bit, + heif_transfer_characteristic_ITU_R_BT_2020_2_12bit, + heif_transfer_characteristic_ITU_R_BT_2100_0_PQ, + heif_transfer_characteristic_SMPTE_ST_428_1, + heif_transfer_characteristic_ITU_R_BT_2100_0_HLG +}; + + +struct heif_error heif_nclx_color_profile_set_transfer_characteristics(struct heif_color_profile_nclx* nclx, uint16_t tc) +{ + if (tc < std::numeric_limits::type>::min() || + tc > std::numeric_limits::type>::max()) { + return Error(heif_error_Invalid_input, heif_suberror_Unknown_NCLX_transfer_characteristics).error_struct(nullptr); + } + + auto n = static_cast(tc); + if (known_transfer_characteristics.find(n) != known_transfer_characteristics.end()) { + nclx->transfer_characteristics = n; + } + else { + nclx->transfer_characteristics = heif_transfer_characteristic_unspecified; + return Error(heif_error_Invalid_input, heif_suberror_Unknown_NCLX_transfer_characteristics).error_struct(nullptr); + } + + return Error::Ok.error_struct(nullptr); +} + + +static const std::set known_matrix_coefficients{ + heif_matrix_coefficients_RGB_GBR, + heif_matrix_coefficients_ITU_R_BT_709_5, + heif_matrix_coefficients_unspecified, + heif_matrix_coefficients_US_FCC_T47, + heif_matrix_coefficients_ITU_R_BT_470_6_System_B_G, + heif_matrix_coefficients_ITU_R_BT_601_6, + heif_matrix_coefficients_SMPTE_240M, + heif_matrix_coefficients_YCgCo, + heif_matrix_coefficients_ITU_R_BT_2020_2_non_constant_luminance, + heif_matrix_coefficients_ITU_R_BT_2020_2_constant_luminance, + heif_matrix_coefficients_SMPTE_ST_2085, + heif_matrix_coefficients_chromaticity_derived_non_constant_luminance, + heif_matrix_coefficients_chromaticity_derived_constant_luminance, + heif_matrix_coefficients_ICtCp +}; + +struct heif_error heif_nclx_color_profile_set_matrix_coefficients(struct heif_color_profile_nclx* nclx, uint16_t mc) +{ + if (mc < std::numeric_limits::type>::min() || + mc > std::numeric_limits::type>::max()) { + return Error(heif_error_Invalid_input, heif_suberror_Unknown_NCLX_matrix_coefficients).error_struct(nullptr); + } + + auto n = static_cast(mc); + if (known_matrix_coefficients.find(n) != known_matrix_coefficients.end()) { + nclx->matrix_coefficients = n; + } + else { + nclx->matrix_coefficients = heif_matrix_coefficients_unspecified; + return Error(heif_error_Invalid_input, heif_suberror_Unknown_NCLX_matrix_coefficients).error_struct(nullptr); + } + + return Error::Ok.error_struct(nullptr); +} + + struct heif_error heif_image_handle_get_nclx_color_profile(const struct heif_image_handle* handle, struct heif_color_profile_nclx** out_data) { diff --git a/libheif/heif.h b/libheif/heif.h index 728434de44..56d8aa72ea 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -209,6 +209,10 @@ enum heif_suberror_code heif_suberror_Unknown_NCLX_color_primaries = 133, + heif_suberror_Unknown_NCLX_transfer_characteristics = 134, + + heif_suberror_Unknown_NCLX_matrix_coefficients = 135, + // --- Memory_allocation_error --- @@ -806,7 +810,13 @@ struct heif_color_profile_nclx }; LIBHEIF_API -struct heif_error heif_nclx_color_profile_set_color_primaries(heif_color_profile_nclx* nclx, uint16_t primaries); +struct heif_error heif_nclx_color_profile_set_color_primaries(struct heif_color_profile_nclx* nclx, uint16_t cp); + +LIBHEIF_API +struct heif_error heif_nclx_color_profile_set_transfer_characteristics(struct heif_color_profile_nclx* nclx, uint16_t transfer_characteristics); + +LIBHEIF_API +struct heif_error heif_nclx_color_profile_set_matrix_coefficients(struct heif_color_profile_nclx* nclx, uint16_t matrix_coefficients); // Returns 'heif_error_Color_profile_does_not_exist' when there is no NCLX profile. // TODO: This function does currently not return an NCLX profile if it is stored in the image bitstream. From 53db640678d34ef4b093c88c06dab483c1c020a3 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 18:24:30 +0100 Subject: [PATCH 0042/3088] disable tautological compare error for clang --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa07dd647f..5584321a0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,9 @@ if(NOT MSVC) add_definitions(-Wno-error=conversion) add_definitions(-Wno-error=unused-parameter) add_definitions(-Wno-error=deprecated-declarations) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + add_definitions(-Wno-error=tautological-constant-out-of-range-compare) + endif () endif() set(CMAKE_CXX_STANDARD 11) From fbd1527bd744d2146cf50da473ecc858b272c34e Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 18:24:51 +0100 Subject: [PATCH 0043/3088] add error codes to emscripten header --- libheif/heif_emscripten.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libheif/heif_emscripten.h b/libheif/heif_emscripten.h index 1e19218337..fcd216a5e6 100644 --- a/libheif/heif_emscripten.h +++ b/libheif/heif_emscripten.h @@ -232,6 +232,9 @@ EMSCRIPTEN_BINDINGS(libheif) { .value("heif_suberror_Security_limit_exceeded", heif_suberror_Security_limit_exceeded) .value("heif_suberror_Unknown_color_profile_type", heif_suberror_Unknown_color_profile_type) .value("heif_suberror_Wrong_tile_image_chroma_format", heif_suberror_Wrong_tile_image_chroma_format) + .value("heif_suberror_Unknown_NCLX_color_primaries", heif_suberror_Unknown_NCLX_color_primaries) + .value("heif_suberror_Unknown_NCLX_transfer_characteristics", heif_suberror_Unknown_NCLX_transfer_characteristics) + .value("heif_suberror_Unknown_NCLX_matrix_coefficients", heif_suberror_Unknown_NCLX_matrix_coefficients) .value("heif_suberror_Invalid_fractional_number", heif_suberror_Invalid_fractional_number) .value("heif_suberror_Invalid_image_size", heif_suberror_Invalid_image_size) .value("heif_suberror_Nonexisting_item_referenced", heif_suberror_Nonexisting_item_referenced) From ea08c14c46927604b838d603f37445d8299d1678 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 18:35:41 +0100 Subject: [PATCH 0044/3088] add new error messages to Go --- go/heif/heif.go | 6 ++++++ libheif/heif_emscripten.h | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/go/heif/heif.go b/go/heif/heif.go index d2ee918f96..020496ce27 100644 --- a/go/heif/heif.go +++ b/go/heif/heif.go @@ -268,6 +268,12 @@ const ( SuberrorWrongTileImagePixelDepth = C.heif_suberror_Wrong_tile_image_pixel_depth + SuberrorUnknownNCLXColorPrimaries = C.heif_suberror_Unknown_NCLX_color_primaries + + SuberrorUnknownNCLXTransferCharacteristics = C.heif_suberror_Unknown_NCLX_transfer_characteristics + + SuberrorUnknownNCLXMatrixCoefficients = C.heif_suberror_Unknown_NCLX_matrix_coefficients + // --- Unsupported_feature --- // Image was coded with an unsupported compression method. diff --git a/libheif/heif_emscripten.h b/libheif/heif_emscripten.h index fcd216a5e6..ed31b1a072 100644 --- a/libheif/heif_emscripten.h +++ b/libheif/heif_emscripten.h @@ -232,9 +232,6 @@ EMSCRIPTEN_BINDINGS(libheif) { .value("heif_suberror_Security_limit_exceeded", heif_suberror_Security_limit_exceeded) .value("heif_suberror_Unknown_color_profile_type", heif_suberror_Unknown_color_profile_type) .value("heif_suberror_Wrong_tile_image_chroma_format", heif_suberror_Wrong_tile_image_chroma_format) - .value("heif_suberror_Unknown_NCLX_color_primaries", heif_suberror_Unknown_NCLX_color_primaries) - .value("heif_suberror_Unknown_NCLX_transfer_characteristics", heif_suberror_Unknown_NCLX_transfer_characteristics) - .value("heif_suberror_Unknown_NCLX_matrix_coefficients", heif_suberror_Unknown_NCLX_matrix_coefficients) .value("heif_suberror_Invalid_fractional_number", heif_suberror_Invalid_fractional_number) .value("heif_suberror_Invalid_image_size", heif_suberror_Invalid_image_size) .value("heif_suberror_Nonexisting_item_referenced", heif_suberror_Nonexisting_item_referenced) @@ -251,7 +248,10 @@ EMSCRIPTEN_BINDINGS(libheif) { .value("heif_suberror_Unsupported_color_conversion", heif_suberror_Unsupported_color_conversion) .value("heif_suberror_Unsupported_item_construction_method", heif_suberror_Unsupported_item_construction_method) .value("heif_suberror_Unsupported_bit_depth", heif_suberror_Unsupported_bit_depth) - .value("heif_suberror_Wrong_tile_image_pixel_depth", heif_suberror_Wrong_tile_image_pixel_depth); + .value("heif_suberror_Wrong_tile_image_pixel_depth", heif_suberror_Wrong_tile_image_pixel_depth) + .value("heif_suberror_Unknown_NCLX_color_primaries", heif_suberror_Unknown_NCLX_color_primaries) + .value("heif_suberror_Unknown_NCLX_transfer_characteristics", heif_suberror_Unknown_NCLX_transfer_characteristics) + .value("heif_suberror_Unknown_NCLX_matrix_coefficients", heif_suberror_Unknown_NCLX_matrix_coefficients); emscripten::enum_("heif_compression_format") .value("heif_compression_undefined", heif_compression_undefined) .value("heif_compression_HEVC", heif_compression_HEVC) From 0c543d5bf671de3c229a7da5f514ae9dd6ce7fb3 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 18:44:03 +0100 Subject: [PATCH 0045/3088] Clang on macOS is named 'AppleClang --- CMakeLists.txt | 2 +- configure.ac | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5584321a0d..9ee014055d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ if(NOT MSVC) add_definitions(-Wno-error=conversion) add_definitions(-Wno-error=unused-parameter) add_definitions(-Wno-error=deprecated-declarations) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_definitions(-Wno-error=tautological-constant-out-of-range-compare) endif () endif() diff --git a/configure.ac b/configure.ac index 8f0c1e96b3..9fbd9ac021 100644 --- a/configure.ac +++ b/configure.ac @@ -303,6 +303,7 @@ CXXFLAGS="$CXXFLAGS $WARNING_FLAGS" CFLAGS="$CFLAGS $WARNING_FLAGS" AC_C_CXX_COMPILE_FLAGS([-Wno-error=potentially-evaluated-expression]) +AC_C_CXX_COMPILE_FLAGS([-Wno-error=tautological-constant-out-of-range-compare]) AC_MSG_NOTICE([---------------------------------------]) AC_MSG_NOTICE([Multithreading: $enable_multithreading]) From 8a78667f7041fe73e61b4b93f095fba45ebb4ebd Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 18:49:31 +0100 Subject: [PATCH 0046/3088] Go is very picky about spaces vs. tabs --- go/heif/heif.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/heif/heif.go b/go/heif/heif.go index 020496ce27..bfe41543bb 100644 --- a/go/heif/heif.go +++ b/go/heif/heif.go @@ -268,11 +268,11 @@ const ( SuberrorWrongTileImagePixelDepth = C.heif_suberror_Wrong_tile_image_pixel_depth - SuberrorUnknownNCLXColorPrimaries = C.heif_suberror_Unknown_NCLX_color_primaries + SuberrorUnknownNCLXColorPrimaries = C.heif_suberror_Unknown_NCLX_color_primaries - SuberrorUnknownNCLXTransferCharacteristics = C.heif_suberror_Unknown_NCLX_transfer_characteristics + SuberrorUnknownNCLXTransferCharacteristics = C.heif_suberror_Unknown_NCLX_transfer_characteristics - SuberrorUnknownNCLXMatrixCoefficients = C.heif_suberror_Unknown_NCLX_matrix_coefficients + SuberrorUnknownNCLXMatrixCoefficients = C.heif_suberror_Unknown_NCLX_matrix_coefficients // --- Unsupported_feature --- From b26d547c6375f377ed53191163ccee37f4a59a3f Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 18:53:22 +0100 Subject: [PATCH 0047/3088] also reduce 'tautological-compare' error to warning --- CMakeLists.txt | 1 + configure.ac | 1 + 2 files changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ee014055d..f522032c53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ if(NOT MSVC) add_definitions(-Wno-error=unused-parameter) add_definitions(-Wno-error=deprecated-declarations) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_definitions(-Wno-error=tautological-compare) add_definitions(-Wno-error=tautological-constant-out-of-range-compare) endif () endif() diff --git a/configure.ac b/configure.ac index 9fbd9ac021..f4f7a2a130 100644 --- a/configure.ac +++ b/configure.ac @@ -303,6 +303,7 @@ CXXFLAGS="$CXXFLAGS $WARNING_FLAGS" CFLAGS="$CFLAGS $WARNING_FLAGS" AC_C_CXX_COMPILE_FLAGS([-Wno-error=potentially-evaluated-expression]) +AC_C_CXX_COMPILE_FLAGS([-Wno-error=tautological-compare]) AC_C_CXX_COMPILE_FLAGS([-Wno-error=tautological-constant-out-of-range-compare]) AC_MSG_NOTICE([---------------------------------------]) From 92677d92541f3364bbaa2040871eaa54da4ed69d Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 19:08:01 +0100 Subject: [PATCH 0048/3088] remove tautological checks from clang-tidy --- .github/workflows/clang.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 02ab82853d..b79f00de25 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -67,4 +67,4 @@ jobs: - name: Run clang-tidy run: | - run-clang-tidy-12 -j$(nproc) + run-clang-tidy-12 -checks=*,-tautological-compare,-tautological-constant-out-of-range-compare -j$(nproc) From ab198166ceed15de32a52c84deb515a2b4dce6a6 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 19:31:02 +0100 Subject: [PATCH 0049/3088] only disable clang-tidy checks --- .github/workflows/clang.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index b79f00de25..7945ee9aa5 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -67,4 +67,4 @@ jobs: - name: Run clang-tidy run: | - run-clang-tidy-12 -checks=*,-tautological-compare,-tautological-constant-out-of-range-compare -j$(nproc) + run-clang-tidy-12 -checks=-tautological-compare,-tautological-constant-out-of-range-compare -j$(nproc) From b85dd797b89944ae63d20688d13a63eb8644d27d Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 19:48:19 +0100 Subject: [PATCH 0050/3088] another try to disable clang-tidy error --- .github/workflows/clang.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 7945ee9aa5..c66e5a8196 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -67,4 +67,4 @@ jobs: - name: Run clang-tidy run: | - run-clang-tidy-12 -checks=-tautological-compare,-tautological-constant-out-of-range-compare -j$(nproc) + run-clang-tidy-12 -checks=-clang-diagnostic-tautological-compare,-clang-diagnostic-tautological-constant-out-of-range-compare -j$(nproc) From 7041ef60a05428e11e667c096b7fd206a7e2858e Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 19:50:06 +0100 Subject: [PATCH 0051/3088] add strict/non-strict decoding modes to heif-convert --- examples/heif_convert.cc | 20 +++++++++++++++++++- libheif/heif.cc | 12 +++++++++++- libheif/heif.h | 12 ++++++++++++ libheif/heif_colorconversion.cc | 5 +++++ libheif/heif_context.cc | 6 ++++++ libheif/heif_decoder_aom.cc | 21 ++++++++++++++++----- libheif/heif_plugin.h | 14 ++++++++++++++ 7 files changed, 83 insertions(+), 7 deletions(-) diff --git a/examples/heif_convert.cc b/examples/heif_convert.cc index d878a97112..19dae34f3d 100644 --- a/examples/heif_convert.cc +++ b/examples/heif_convert.cc @@ -91,12 +91,17 @@ int main(int argc, char** argv) { int opt; int quality = -1; // Use default quality. + bool strict_decoding = false; + UNUSED(quality); // The quality will only be used by encoders that support it. - while ((opt = getopt(argc, argv, "q:")) != -1) { + while ((opt = getopt(argc, argv, "q:s")) != -1) { switch (opt) { case 'q': quality = atoi(optarg); break; + case 's': + strict_decoding = true; + break; default: /* '?' */ return usage(argv[0]); } @@ -230,6 +235,8 @@ int main(int argc, char** argv) struct heif_decoding_options* decode_options = heif_decoding_options_alloc(); encoder->UpdateDecodingOptions(handle, decode_options); + decode_options->strict_decoding = strict_decoding; + int bit_depth = heif_image_handle_get_luma_bits_per_pixel(handle); if (bit_depth < 0) { heif_decoding_options_free(decode_options); @@ -252,6 +259,17 @@ int main(int argc, char** argv) return 1; } + // show decoding warnings + + for (int i = 0;; i++) { + int n = heif_image_get_decoding_warnings(image, i, &err, 1); + if (n == 0) { + break; + } + + std::cerr << "Warning: " << err.message << "\n"; + } + if (image) { bool written = encoder->Encode(handle, image, filename); if (!written) { diff --git a/libheif/heif.cc b/libheif/heif.cc index 6e765e4a8a..239ebdcdd9 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -883,7 +883,7 @@ heif_decoding_options* heif_decoding_options_alloc() { auto options = new heif_decoding_options; - options->version = 2; + options->version = 3; options->ignore_transformations = false; @@ -896,6 +896,10 @@ heif_decoding_options* heif_decoding_options_alloc() options->convert_hdr_to_8bit = false; + // version 3 + + options->strict_decoding = false; + return options; } @@ -965,6 +969,12 @@ int heif_image_get_decoding_warnings(struct heif_image* image, } } +void heif_image_add_decoding_warning(struct heif_image* image, + struct heif_error err) +{ + image->image->add_warning(Error(err.code, err.subcode)); +} + void heif_image_release(const struct heif_image* img) { diff --git a/libheif/heif.h b/libheif/heif.h index 56d8aa72ea..b5624523d6 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -43,6 +43,7 @@ extern "C" { // 1.9.2 1 2 2 1 1 1 // 1.10 1 2 3 1 1 1 // 1.11 1 2 4 1 1 1 +// 1.13 1 3 4 1 1 1 #if defined(_MSC_VER) && !defined(LIBHEIF_STATIC_BUILD) @@ -940,6 +941,12 @@ struct heif_decoding_options // version 2 options uint8_t convert_hdr_to_8bit; + + // version 3 options + + // When enabled, an error is returned for invalid input. Otherwise, it will try its best and + // add decoding warnings to the decoded heif_image. Default is non-strict. + uint8_t strict_decoding; }; @@ -1070,6 +1077,11 @@ int heif_image_get_decoding_warnings(struct heif_image* image, struct heif_error* out_warnings, int max_output_buffer_entries); +// This function is only for decoder plugin implementors. +LIBHEIF_API +void heif_image_add_decoding_warning(struct heif_image* image, + struct heif_error err); + // Release heif_image. LIBHEIF_API void heif_image_release(const struct heif_image*); diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc index ce492ca70e..2b05068460 100644 --- a/libheif/heif_colorconversion.cc +++ b/libheif/heif_colorconversion.cc @@ -3217,6 +3217,11 @@ std::shared_ptr ColorConversionPipeline::convert_image(const std out->set_premultiplied_alpha(in->is_premultiplied_alpha()); + auto warnings = in->get_warnings(); + for (const auto& warning : warnings) { + out->add_warning(warning); + } + in = out; } diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index 6916b18bda..13642a0e4d 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -1088,6 +1088,12 @@ Error HeifContext::decode_image_planar(heif_item_id ID, return Error(err.code, err.subcode, err.message); } + if (decoder_plugin->plugin_api_version >= 2) { + if (decoder_plugin->set_strict_decoding) { + decoder_plugin->set_strict_decoding(decoder, options->strict_decoding); + } + } + err = decoder_plugin->push_data(decoder, data.data(), data.size()); if (err.code != heif_error_Ok) { decoder_plugin->free_decoder(decoder); diff --git a/libheif/heif_decoder_aom.cc b/libheif/heif_decoder_aom.cc index 3a4ac46fbd..ca6eb0d87f 100644 --- a/libheif/heif_decoder_aom.cc +++ b/libheif/heif_decoder_aom.cc @@ -39,6 +39,8 @@ struct aom_decoder bool codec_initialized = false; aom_codec_iface_t* iface; + + bool strict_decoding = false; }; static const char kSuccess[] = "Success"; @@ -126,6 +128,14 @@ void aom_free_decoder(void* decoder_raw) } +void aom_set_strict_decoding(void* decoder_raw, int flag) +{ + struct aom_decoder* decoder = (aom_decoder*) decoder_raw; + + decoder->strict_decoding = flag; +} + + struct heif_error aom_push_data(void* decoder_raw, const void* frame_data, size_t frame_size) { struct aom_decoder* decoder = (struct aom_decoder*) decoder_raw; @@ -203,9 +213,9 @@ struct heif_error aom_decode_image(void* decoder_raw, struct heif_image** out_im // --- read nclx parameters from decoded AV1 bitstream heif_color_profile_nclx nclx; - nclx.color_primaries = (heif_color_primaries) img->cp; - nclx.transfer_characteristics = (heif_transfer_characteristics) img->tc; - nclx.matrix_coefficients = (heif_matrix_coefficients) img->mc; + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, img->cp)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, img->tc + 200)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, img->mc)); nclx.full_range_flag = (img->range == AOM_CR_FULL_RANGE); heif_image_set_nclx_color_profile(heif_img, &nclx); @@ -259,7 +269,7 @@ struct heif_error aom_decode_image(void* decoder_raw, struct heif_image** out_im static const struct heif_decoder_plugin decoder_aom { - 1, + 2, aom_plugin_name, aom_init_plugin, aom_deinit_plugin, @@ -267,7 +277,8 @@ static const struct heif_decoder_plugin decoder_aom aom_new_decoder, aom_free_decoder, aom_push_data, - aom_decode_image + aom_decode_image, + aom_set_strict_decoding }; diff --git a/libheif/heif_plugin.h b/libheif/heif_plugin.h index 609c426c03..5b64be2c19 100644 --- a/libheif/heif_plugin.h +++ b/libheif/heif_plugin.h @@ -40,6 +40,7 @@ extern "C" { // 1.1 1 1 1 // 1.4 1 1 2 // 1.8 1 2 2 +// 1.13 2 2 2 // ==================================================================================================== @@ -88,6 +89,8 @@ struct heif_decoder_plugin // --- version 2 functions will follow below ... --- + void (*set_strict_decoding)(void* decoder, int flag); + // If not NULL, this can provide a specialized function to convert YCbCr to sRGB, because // only the codec itself knows how to interpret the chroma samples and their locations. /* @@ -276,6 +279,17 @@ extern struct heif_error heif_error_ok; extern struct heif_error heif_error_unsupported_parameter; extern struct heif_error heif_error_invalid_parameter_value; +#define HEIF_WARN_OR_FAIL(strict, image, cmd) \ +{ struct heif_error e = cmd; \ + if (e.code != heif_error_Ok) { \ + if (strict) { \ + return e; \ + } \ + else { \ + heif_image_add_decoding_warning(image, e); \ + } \ + } \ +} #ifdef __cplusplus } #endif From e8288cd3f414efdb0f9d5a409aceca4c2624a9f5 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 20:08:21 +0100 Subject: [PATCH 0052/3088] warn on invalid NCLX params in dav1d decoder plugin --- libheif/heif_decoder_aom.cc | 2 +- libheif/heif_decoder_dav1d.cc | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libheif/heif_decoder_aom.cc b/libheif/heif_decoder_aom.cc index ca6eb0d87f..1608a7a2f7 100644 --- a/libheif/heif_decoder_aom.cc +++ b/libheif/heif_decoder_aom.cc @@ -214,7 +214,7 @@ struct heif_error aom_decode_image(void* decoder_raw, struct heif_image** out_im heif_color_profile_nclx nclx; HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, img->cp)); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, img->tc + 200)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, img->tc)); HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, img->mc)); nclx.full_range_flag = (img->range == AOM_CR_FULL_RANGE); heif_image_set_nclx_color_profile(heif_img, &nclx); diff --git a/libheif/heif_decoder_dav1d.cc b/libheif/heif_decoder_dav1d.cc index 4a2f1e29b6..a6c42e4f87 100644 --- a/libheif/heif_decoder_dav1d.cc +++ b/libheif/heif_decoder_dav1d.cc @@ -39,6 +39,7 @@ struct dav1d_decoder Dav1dSettings settings; Dav1dContext* context; Dav1dData data; + bool strict_decoding = false; }; static const char kEmptyString[] = ""; @@ -127,6 +128,13 @@ void dav1d_free_decoder(void* decoder_raw) } +void dav1d_set_strict_decoding(void* decoder_raw, int flag) +{ + struct dav1d_decoder* decoder = (dav1d_decoder*) decoder_raw; + + decoder->strict_decoding = flag; +} + struct heif_error dav1d_push_data(void* decoder_raw, const void* frame_data, size_t frame_size) { auto* decoder = (struct dav1d_decoder*) decoder_raw; @@ -224,9 +232,9 @@ struct heif_error dav1d_decode_image(void* decoder_raw, struct heif_image** out_ // --- read nclx parameters from decoded AV1 bitstream heif_color_profile_nclx nclx; - nclx.color_primaries = (heif_color_primaries) frame.seq_hdr->pri; - nclx.transfer_characteristics = (heif_transfer_characteristics) frame.seq_hdr->trc; - nclx.matrix_coefficients = (heif_matrix_coefficients) frame.seq_hdr->mtrx; + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, frame.seq_hdr->pri)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, frame.seq_hdr->trc)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, frame.seq_hdr->mtrx)); nclx.full_range_flag = (frame.seq_hdr->color_range != 0); heif_image_set_nclx_color_profile(heif_img, &nclx); @@ -285,7 +293,7 @@ struct heif_error dav1d_decode_image(void* decoder_raw, struct heif_image** out_ static const struct heif_decoder_plugin decoder_dav1d { - 1, + 2, dav1d_plugin_name, dav1d_init_plugin, dav1d_deinit_plugin, @@ -293,7 +301,8 @@ static const struct heif_decoder_plugin decoder_dav1d dav1d_new_decoder, dav1d_free_decoder, dav1d_push_data, - dav1d_decode_image + dav1d_decode_image, + dav1d_set_strict_decoding }; From 19b11c9a3193baad241948c6b2f5d99da4a3d1e1 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 20:18:09 +0100 Subject: [PATCH 0053/3088] warn on invalid NCLX params in libde265 decoder plugin --- libheif/heif_decoder_libde265.cc | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/libheif/heif_decoder_libde265.cc b/libheif/heif_decoder_libde265.cc index 3e04b76f3b..2fcabd54b4 100644 --- a/libheif/heif_decoder_libde265.cc +++ b/libheif/heif_decoder_libde265.cc @@ -39,6 +39,7 @@ using namespace heif; struct libde265_decoder { de265_decoder_context* ctx; + bool strict_decoding = false; }; static const char kEmptyString[] = ""; @@ -189,6 +190,14 @@ static void libde265_free_decoder(void* decoder_raw) } +void libde265_set_strict_decoding(void* decoder_raw, int flag) +{ + struct libde265_decoder* decoder = (libde265_decoder*) decoder_raw; + + decoder->strict_decoding = flag; +} + + #if LIBDE265_NUMERIC_VERSION >= 0x02000000 static struct heif_error libde265_v2_push_data(void* decoder_raw, const void* data, size_t size) @@ -330,15 +339,15 @@ static struct heif_error libde265_v1_decode_image(void* decoder_raw, return err; } - auto nclx = std::make_shared(); + struct heif_color_profile_nclx* nclx = heif_nclx_color_profile_alloc(); #if LIBDE265_NUMERIC_VERSION >= 0x01000700 - nclx->set_full_range_flag(de265_get_image_full_range_flag(image)); - nclx->set_matrix_coefficients((uint16_t)de265_get_image_matrix_coefficients(image)); - nclx->set_colour_primaries((uint16_t)de265_get_image_colour_primaries(image)); - nclx->set_transfer_characteristics((uint16_t)de265_get_image_transfer_characteristics(image)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_color_primaries(nclx, (uint16_t)de265_get_image_colour_primaries(image))); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_transfer_characteristics(nclx, (uint16_t)de265_get_image_transfer_characteristics(image))); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_matrix_coefficients(nclx, (uint16_t)de265_get_image_matrix_coefficients(image))); + nclx->full_range_flag = (bool)de265_get_image_full_range_flag(image); #endif - assert(*out_img); - (*out_img)->image->set_color_profile_nclx(nclx); + heif_image_set_nclx_color_profile(*out_img, nclx); + heif_nclx_color_profile_free(nclx); de265_release_next_picture(decoder->ctx); } @@ -370,7 +379,7 @@ static const struct heif_decoder_plugin decoder_libde265 static const struct heif_decoder_plugin decoder_libde265 { - 1, + 2, libde265_plugin_name, libde265_init_plugin, libde265_deinit_plugin, @@ -378,7 +387,8 @@ static const struct heif_decoder_plugin decoder_libde265 libde265_new_decoder, libde265_free_decoder, libde265_v1_push_data, - libde265_v1_decode_image + libde265_v1_decode_image, + libde265_set_strict_decoding }; #endif From 8d8c0ef1788e6e32e961ef4c512ad8af7ce5b62e Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 20:31:26 +0100 Subject: [PATCH 0054/3088] heif_enc checks for valid nclx input parameters --- examples/heif_enc.cc | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 00c4f9f2df..162f0056a9 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -72,9 +72,9 @@ int two_colr_boxes = 0; int premultiplied_alpha = 0; const char* encoderId = nullptr; -int nclx_matrix_coefficients = 6; -int nclx_colour_primaries = 2; -int nclx_transfer_characteristic = 2; +uint16_t nclx_matrix_coefficients = 6; +uint16_t nclx_colour_primaries = 2; +uint16_t nclx_transfer_characteristic = 2; int nclx_full_range = true; const int OPTION_NCLX_MATRIX_COEFFICIENTS = 1000; @@ -1065,13 +1065,13 @@ int main(int argc, char** argv) encoderId = optarg; break; case OPTION_NCLX_MATRIX_COEFFICIENTS: - nclx_matrix_coefficients = atoi(optarg); + nclx_matrix_coefficients = (uint16_t)strtoul(optarg, nullptr, 0); break; case OPTION_NCLX_COLOUR_PRIMARIES: - nclx_colour_primaries = atoi(optarg); + nclx_colour_primaries = (uint16_t)strtoul(optarg, nullptr, 0); break; case OPTION_NCLX_TRANSFER_CHARACTERISTIC: - nclx_transfer_characteristic = atoi(optarg); + nclx_transfer_characteristic = (uint16_t)strtoul(optarg, nullptr, 0); break; case OPTION_NCLX_FULL_RANGE_FLAG: nclx_full_range = atoi(optarg); @@ -1215,9 +1215,21 @@ int main(int argc, char** argv) } heif_color_profile_nclx nclx; - nclx.matrix_coefficients = (heif_matrix_coefficients) nclx_matrix_coefficients; - nclx.transfer_characteristics = (heif_transfer_characteristics) nclx_transfer_characteristic; - nclx.color_primaries = (heif_color_primaries) nclx_colour_primaries; + error = heif_nclx_color_profile_set_matrix_coefficients(&nclx, nclx_matrix_coefficients); + if (error.code) { + std::cerr << "Invalid matrix coefficients specified.\n"; + exit(5); + } + error = heif_nclx_color_profile_set_transfer_characteristics(&nclx, nclx_transfer_characteristic); + if (error.code) { + std::cerr << "Invalid transfer characteristics specified.\n"; + exit(5); + } + error = heif_nclx_color_profile_set_color_primaries(&nclx, nclx_colour_primaries); + if (error.code) { + std::cerr << "Invalid color primaries specified.\n"; + exit(5); + } nclx.full_range_flag = (uint8_t) nclx_full_range; //heif_image_set_nclx_color_profile(image.get(), &nclx); From 03fe49fbfc613ebead9596d00715f663a20209b3 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 20:35:37 +0100 Subject: [PATCH 0055/3088] sanitize nclx when reading HEIF metadata --- libheif/box.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/libheif/box.cc b/libheif/box.cc index 8cae4fdad4..f48d781f08 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -1694,10 +1694,25 @@ Error color_profile_nclx::get_nclx_color_profile(struct heif_color_profile_nclx* struct heif_color_profile_nclx* nclx = *out_data; + struct heif_error err; + nclx->version = 1; - nclx->color_primaries = (enum heif_color_primaries) get_colour_primaries(); - nclx->transfer_characteristics = (enum heif_transfer_characteristics) get_transfer_characteristics(); - nclx->matrix_coefficients = (enum heif_matrix_coefficients) get_matrix_coefficients(); + + err = heif_nclx_color_profile_set_color_primaries(nclx, get_colour_primaries()); + if (err.code) { + return {err.code, err.subcode}; + } + + err = heif_nclx_color_profile_set_transfer_characteristics(nclx, get_transfer_characteristics()); + if (err.code) { + return {err.code, err.subcode}; + } + + err = heif_nclx_color_profile_set_matrix_coefficients(nclx, get_matrix_coefficients()); + if (err.code) { + return {err.code, err.subcode}; + } + nclx->full_range_flag = get_full_range_flag(); // fill color primaries From 4ad90c5c165062cbc87156a2c8f5037d9f782c99 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 20:36:49 +0100 Subject: [PATCH 0056/3088] set nclx color profile defaults to 'unspecified' --- libheif/box.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libheif/box.h b/libheif/box.h index 6f418a93ff..bbb8cc1477 100644 --- a/libheif/box.h +++ b/libheif/box.h @@ -1167,9 +1167,9 @@ namespace heif { void set_from_heif_color_profile_nclx(const struct heif_color_profile_nclx* nclx); private: - uint16_t m_colour_primaries = 0; - uint16_t m_transfer_characteristics = 0; - uint16_t m_matrix_coefficients = 0; + uint16_t m_colour_primaries = heif_color_primaries_unspecified; + uint16_t m_transfer_characteristics = heif_transfer_characteristic_unspecified; + uint16_t m_matrix_coefficients = heif_matrix_coefficients_unspecified; bool m_full_range_flag = true; }; From 9497e10168660138fd10a738179039c0e7d7ba6c Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 20:38:13 +0100 Subject: [PATCH 0057/3088] avoid division by zero (should never happen) --- libheif/nclx.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libheif/nclx.cc b/libheif/nclx.cc index 0c35b6cd14..b81b7d7cd6 100644 --- a/libheif/nclx.cc +++ b/libheif/nclx.cc @@ -82,6 +82,10 @@ heif::Kr_Kb heif::get_Kr_Kb(uint16_t matrix_coefficients_idx, uint16_t primaries float denom = p.whiteY * (p.redX * (p.greenY * zb - p.blueY * zg) + p.greenX * (p.blueY * zr - p.redY * zb) + p.blueX * (p.redY * zg - p.greenY * zr)); + if (denom == 0.0f) { + return result; + } + result.Kr = (p.redY * (p.whiteX * (p.greenY * zb - p.blueY * zg) + p.whiteY * (p.blueX * zg - p.greenX * zb) + zw * (p.greenX * p.blueY - p.blueX * p.greenY))) / denom; result.Kb = (p.blueY * (p.whiteX * (p.redY * zg - p.greenY * zr) + p.whiteY * (p.greenX * zr - p.redX * zg) + From 37c5ae0d6d4b90011f2e4b25a06e93b4e29ff4b0 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 21 Feb 2022 23:01:11 +0100 Subject: [PATCH 0058/3088] fix segfault when decoding options is nullptr --- libheif/heif_context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index 13642a0e4d..e13fc2739f 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -1090,7 +1090,7 @@ Error HeifContext::decode_image_planar(heif_item_id ID, if (decoder_plugin->plugin_api_version >= 2) { if (decoder_plugin->set_strict_decoding) { - decoder_plugin->set_strict_decoding(decoder, options->strict_decoding); + decoder_plugin->set_strict_decoding(decoder, options ? options->strict_decoding : false); } } From d81f9f8222e343eeabb1735f80532555b41908b5 Mon Sep 17 00:00:00 2001 From: Jamaika1 Date: Tue, 22 Feb 2022 19:48:24 +0100 Subject: [PATCH 0059/3088] 3rd party: Update dav1d to 0.9.2 --- third-party/dav1d.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/dav1d.cmd b/third-party/dav1d.cmd index 7895968305..b8a2698e36 100644 --- a/third-party/dav1d.cmd +++ b/third-party/dav1d.cmd @@ -10,7 +10,7 @@ : # If you're running this on Windows, be sure you've already run this (from your VC2019 install dir): : # "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" -git clone -b 0.8.2 --depth 1 https://code.videolan.org/videolan/dav1d.git +git clone -b 0.9.2 --depth 1 https://code.videolan.org/videolan/dav1d.git cd dav1d From 5de6ed30131c402460e2dbb74588ef38e273287b Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Wed, 23 Feb 2022 10:45:22 +0100 Subject: [PATCH 0060/3088] write JPEG Exif markers > 64k (see #610) --- examples/encoder_jpeg.cc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/examples/encoder_jpeg.cc b/examples/encoder_jpeg.cc index 64c772458f..8c1ae29a0b 100644 --- a/examples/encoder_jpeg.cc +++ b/examples/encoder_jpeg.cc @@ -59,11 +59,12 @@ void JpegEncoder::OnJpegError(j_common_ptr cinfo) longjmp(handler->setjmp_buffer, 1); } +#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ + #if !defined(HAVE_JPEG_WRITE_ICC_PROFILE) #define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ #define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ -#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ #define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) /* @@ -166,10 +167,25 @@ bool JpegEncoder::Encode(const struct heif_image_handle* handle, size_t exifsize = 0; uint8_t* exifdata = GetExifMetaData(handle, &exifsize); - if (exifdata && exifsize > 4) { - static const uint8_t kExifMarker = JPEG_APP0 + 1; - jpeg_write_marker(&cinfo, kExifMarker, exifdata + 4, - static_cast(exifsize - 4)); + if (exifdata) { + if (exifsize > 4) { + static const uint8_t kExifMarker = JPEG_APP0 + 1; + + uint8_t* ptr = exifdata + 4; + size_t size = exifsize - 4; + + while (size > MAX_BYTES_IN_MARKER) { + jpeg_write_marker(&cinfo, kExifMarker, ptr, + static_cast(MAX_BYTES_IN_MARKER)); + + ptr += MAX_BYTES_IN_MARKER; + size -= MAX_BYTES_IN_MARKER; + } + + jpeg_write_marker(&cinfo, kExifMarker, ptr, + static_cast(size)); + } + free(exifdata); } From ad4f9a5794282626178feb4f2219372c5fe535d3 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Wed, 23 Feb 2022 10:58:51 +0100 Subject: [PATCH 0061/3088] skip extra data at Exif header so that we start saving at the 'Exif' ID --- examples/encoder_jpeg.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/encoder_jpeg.cc b/examples/encoder_jpeg.cc index 8c1ae29a0b..84767730f7 100644 --- a/examples/encoder_jpeg.cc +++ b/examples/encoder_jpeg.cc @@ -171,8 +171,16 @@ bool JpegEncoder::Encode(const struct heif_image_handle* handle, if (exifsize > 4) { static const uint8_t kExifMarker = JPEG_APP0 + 1; - uint8_t* ptr = exifdata + 4; - size_t size = exifsize - 4; + uint32_t skip = (exifdata[0]<<24) | (exifdata[1]<<16) | (exifdata[2]<<8) | exifdata[3]; + if (skip>=6) { + skip = 4 + skip-6; + } + else { + skip = 4; + } + + uint8_t* ptr = exifdata + skip; + size_t size = exifsize - skip; while (size > MAX_BYTES_IN_MARKER) { jpeg_write_marker(&cinfo, kExifMarker, ptr, From cf7feb538339d951fa0d88510cf10a7bfa4318a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 13:13:20 +0000 Subject: [PATCH 0062/3088] Bump actions/upload-artifact from 2.3.1 to 3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2.3.1 to 3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2.3.1...v3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/cifuzz.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 7eb22a7fcf..59208f8693 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -17,7 +17,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v2.3.1 + uses: actions/upload-artifact@v3 if: failure() && steps.build.outcome == 'success' with: name: artifacts From 1bb5d74e7ca957d9a2008dabc09da20b751ecf8e Mon Sep 17 00:00:00 2001 From: Jamaika1 Date: Sat, 19 Mar 2022 08:57:16 +0100 Subject: [PATCH 0063/3088] 3rd party: Update dav1d to 1.0.0 --- third-party/dav1d.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/dav1d.cmd b/third-party/dav1d.cmd index b8a2698e36..551823addc 100644 --- a/third-party/dav1d.cmd +++ b/third-party/dav1d.cmd @@ -10,7 +10,7 @@ : # If you're running this on Windows, be sure you've already run this (from your VC2019 install dir): : # "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" -git clone -b 0.9.2 --depth 1 https://code.videolan.org/videolan/dav1d.git +git clone -b 1.0.0 --depth 1 https://code.videolan.org/videolan/dav1d.git cd dav1d From fef75da07d33f9a03e8c5b8eec299d0ece2e47e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 13:14:55 +0000 Subject: [PATCH 0064/3088] Bump actions/cache from 2 to 3 Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Commits](https://github.com/actions/cache/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/coverity.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 78a449cc94..6ce9fde5ec 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v2 - name: Cache Coverity build tool - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: | coverity_tool.tar.gz From af4872b21062bebaef8cb3ea66a0f6904a006c1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Mar 2022 07:39:52 +0000 Subject: [PATCH 0065/3088] Bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/clang.yml | 4 ++-- .github/workflows/coverity.yml | 2 +- .github/workflows/diagram.yml | 2 +- .github/workflows/emscripten.yml | 2 +- .github/workflows/fuzzer.yml | 2 +- .github/workflows/go.yml | 2 +- .github/workflows/lint.yml | 4 ++-- .github/workflows/mingw.yml | 2 +- .github/workflows/osx.yml | 2 +- .github/workflows/test.yml | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 91766ca8b8..82897484e8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: env: ${{ matrix.env }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index c66e5a8196..feb5879986 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -17,7 +17,7 @@ jobs: env: ${{ matrix.env }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | @@ -50,7 +50,7 @@ jobs: CLANG_TIDY: 1 runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 6ce9fde5ec..53da5b9697 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -14,7 +14,7 @@ jobs: WITH_LIBDE265: 1 WITH_X265: 1 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache Coverity build tool uses: actions/cache@v3 diff --git a/.github/workflows/diagram.yml b/.github/workflows/diagram.yml index 5ef516231f..1901b7a27a 100644 --- a/.github/workflows/diagram.yml +++ b/.github/workflows/diagram.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@master + uses: actions/checkout@v3 - name: Update diagram uses: githubocto/repo-visualizer@main with: diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index ac6b73bbce..b5d0b041e4 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -12,7 +12,7 @@ jobs: EMSCRIPTEN_VERSION: 1.37.26 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install emscripten run: | diff --git a/.github/workflows/fuzzer.yml b/.github/workflows/fuzzer.yml index 184b1e4189..3d7f37aa4e 100644 --- a/.github/workflows/fuzzer.yml +++ b/.github/workflows/fuzzer.yml @@ -16,7 +16,7 @@ jobs: FUZZER: 1 runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 31ae266bb4..c60117e6ce 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -20,7 +20,7 @@ jobs: GO: 1 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/setup-go@v2 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7861b74499..ee7c691b6c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: CPPLINT: 1 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | @@ -31,7 +31,7 @@ jobs: CHECK_LICENSES: 1 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 0b75b4cb81..5027edfc62 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -16,7 +16,7 @@ jobs: env: ${{ matrix.env }} runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | diff --git a/.github/workflows/osx.yml b/.github/workflows/osx.yml index 7520e65091..30d85d1833 100644 --- a/.github/workflows/osx.yml +++ b/.github/workflows/osx.yml @@ -18,7 +18,7 @@ jobs: env: ${{ matrix.env }} runs-on: macos-10.15 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0b871dbe50..36d0a90544 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: TESTS: 1 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | From 7ccfd989d59608be2e45a71869ce4bf8e18abee7 Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Sun, 27 Mar 2022 11:51:27 -0700 Subject: [PATCH 0066/3088] Fix typos in the heif-enc help message --- examples/heif_enc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 162f0056a9..aef563eb82 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -139,12 +139,12 @@ void show_help(const char* argv0) << " --colour_primaries nclx profile: color primaries (see h.273)\n" << " --transfer_characteristic nclx profile: transfer characteristics (see h.273)\n" << " --full_range_flag nclx profile: full range flag, default: 1\n" - << " --enable-two-colr-boxes will write both an ICC and an nclx color profile if both a present\n" + << " --enable-two-colr-boxes will write both an ICC and an nclx color profile if both are present\n" << " --premultiplied-alpha input image has premultiplied alpha\n" << "\n" << "Note: to get lossless encoding, you need this set of options:\n" << " -L switch encoder to lossless mode\n" - << " -p chroma=444 switch off color subsampling\n" + << " -p chroma=444 switch off chroma subsampling\n" << " --matrix_coefficients=0 encode in RGB color-space\n"; } From 330ae3bf1138891db4b7486571d6b35b5d9d5fce Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 4 Apr 2022 19:26:27 +0200 Subject: [PATCH 0067/3088] replace getopt() with getopt_long() heif-convert --- examples/heif_convert.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/heif_convert.cc b/examples/heif_convert.cc index 19dae34f3d..eb474c6439 100644 --- a/examples/heif_convert.cc +++ b/examples/heif_convert.cc @@ -28,6 +28,7 @@ #endif #include +#include #if defined(HAVE_UNISTD_H) @@ -87,15 +88,27 @@ class ContextReleaser struct heif_context* ctx_; }; + +static struct option long_options[] = { + {(char* const) "quality", required_argument, 0, 'q'}, + {(char* const) "strict", no_argument, 0, 's'} +}; + int main(int argc, char** argv) { - int opt; int quality = -1; // Use default quality. bool strict_decoding = false; UNUSED(quality); // The quality will only be used by encoders that support it. - while ((opt = getopt(argc, argv, "q:s")) != -1) { - switch (opt) { + //while ((opt = getopt(argc, argv, "q:s")) != -1) { + while (true) { + int option_index = 0; + int c = getopt_long(argc, argv, "q:s", long_options, &option_index); + if (c == -1) { + break; + } + + switch (c) { case 'q': quality = atoi(optarg); break; From 6fdfe17a0fa3a3cb3964988102e04e4c16f48635 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 4 Apr 2022 19:44:01 +0200 Subject: [PATCH 0068/3088] add --quiet option to heif-convert --- examples/heif_convert.cc | 44 ++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/examples/heif_convert.cc b/examples/heif_convert.cc index eb474c6439..2e7dabbf4c 100644 --- a/examples/heif_convert.cc +++ b/examples/heif_convert.cc @@ -67,12 +67,19 @@ #define UNUSED(x) (void)x -static int usage(const char* command) +static void show_help(const char* argv0) { - fprintf(stderr, "USAGE: %s [-q quality 0..100] \n", command); - return 1; + std::cerr << " heif-convert libheif version: " << heif_get_version() << "\n" + << "-------------------------------------------\n" + << "Usage: heif-convert [options] \n" + << "\n" + << "Options:\n" + " -h, --help show help\n" + " -q, --quality quality (for JPEG output)\n" + " --quiet do not output status messages to console\n"; } + class ContextReleaser { public: @@ -89,9 +96,13 @@ class ContextReleaser }; +int option_quiet = 0; + static struct option long_options[] = { {(char* const) "quality", required_argument, 0, 'q'}, - {(char* const) "strict", no_argument, 0, 's'} + {(char* const) "strict", no_argument, 0, 's'}, + {(char* const) "quiet", no_argument, &option_quiet, 1}, + {(char* const) "help", no_argument, 0, 'h'} }; int main(int argc, char** argv) @@ -115,14 +126,17 @@ int main(int argc, char** argv) case 's': strict_decoding = true; break; - default: /* '?' */ - return usage(argv[0]); + case '?': + case 'h': + show_help(argv[0]); + return 0; } } if (optind + 2 > argc) { // Need input and output filenames as additional arguments. - return usage(argv[0]); + show_help(argv[0]); + return 5; } std::string input_filename(argv[optind++]); @@ -214,7 +228,9 @@ int main(int argc, char** argv) return 1; } - printf("File contains %d images\n", num_images); + if (!option_quiet) { + std::cout << "File contains " << num_images << " image" << (num_images>1 ? "s" : "") << "\n"; + } std::vector image_IDs(num_images); num_images = heif_context_get_list_of_top_level_image_IDs(ctx, image_IDs.data(), num_images); @@ -289,7 +305,9 @@ int main(int argc, char** argv) fprintf(stderr, "could not write image\n"); } else { - printf("Written to %s\n", filename.c_str()); + if (!option_quiet) { + std::cout << "Written to " << filename << "\n"; + } } heif_image_release(image); @@ -334,7 +352,9 @@ int main(int argc, char** argv) fprintf(stderr, "could not write depth image\n"); } else { - printf("Depth image written to %s\n", s.str().c_str()); + if (!option_quiet) { + std::cout << "Depth image written to " << s.str() << "\n"; + } } heif_image_release(depth_image); @@ -400,7 +420,9 @@ int main(int argc, char** argv) fprintf(stderr, "could not write auxiliary image\n"); } else { - printf("Auxiliary image written to %s\n", s.str().c_str()); + if (!option_quiet) { + std::cout << "Auxiliary image written to " << s.str().c_str() << "\n"; + } } heif_image_release(aux_image); From bf2d1c6fdcbb6415a494f93a05beb76e7b0d652c Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 4 Apr 2022 19:46:36 +0200 Subject: [PATCH 0069/3088] heif-convert: list the allowed output filename suffices --- examples/heif_convert.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/heif_convert.cc b/examples/heif_convert.cc index 2e7dabbf4c..601de699f2 100644 --- a/examples/heif_convert.cc +++ b/examples/heif_convert.cc @@ -71,9 +71,12 @@ static void show_help(const char* argv0) { std::cerr << " heif-convert libheif version: " << heif_get_version() << "\n" << "-------------------------------------------\n" - << "Usage: heif-convert [options] \n" - << "\n" - << "Options:\n" + "Usage: heif-convert [options] \n" + "\n" + "The program determines the output file format from the output filename suffix.\n" + "These suffices are recognized: jpg, jpeg, png, y4m." + "\n" + "Options:\n" " -h, --help show help\n" " -q, --quality quality (for JPEG output)\n" " --quiet do not output status messages to console\n"; From 2c4baa28d382e7eb1000d52899cc2dcf2b8afeb1 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 4 Apr 2022 19:53:38 +0200 Subject: [PATCH 0070/3088] heif-convert: only output aux images when explicitly requested --- examples/heif_convert.cc | 194 ++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 93 deletions(-) diff --git a/examples/heif_convert.cc b/examples/heif_convert.cc index 601de699f2..dbd457d3f9 100644 --- a/examples/heif_convert.cc +++ b/examples/heif_convert.cc @@ -77,9 +77,10 @@ static void show_help(const char* argv0) "These suffices are recognized: jpg, jpeg, png, y4m." "\n" "Options:\n" - " -h, --help show help\n" - " -q, --quality quality (for JPEG output)\n" - " --quiet do not output status messages to console\n"; + " -h, --help show help\n" + " -q, --quality quality (for JPEG output)\n" + " --with-aux also write auxiliary images (e.g. depth images)\n" + " --quiet do not output status messages to console\n"; } @@ -100,11 +101,13 @@ class ContextReleaser int option_quiet = 0; +int option_aux = 0; static struct option long_options[] = { {(char* const) "quality", required_argument, 0, 'q'}, {(char* const) "strict", no_argument, 0, 's'}, {(char* const) "quiet", no_argument, &option_quiet, 1}, + {(char* const) "with-aux", no_argument, &option_aux, 1}, {(char* const) "help", no_argument, 0, 'h'} }; @@ -130,6 +133,8 @@ int main(int argc, char** argv) strict_decoding = true; break; case '?': + std::cerr << "\n"; + // falltrough case 'h': show_help(argv[0]); return 0; @@ -315,125 +320,128 @@ int main(int argc, char** argv) heif_image_release(image); - int has_depth = heif_image_handle_has_depth_image(handle); - if (has_depth) { - heif_item_id depth_id; - int nDepthImages = heif_image_handle_get_list_of_depth_image_IDs(handle, &depth_id, 1); - assert(nDepthImages == 1); - (void) nDepthImages; + if (option_aux) { + int has_depth = heif_image_handle_has_depth_image(handle); + if (has_depth) { + heif_item_id depth_id; + int nDepthImages = heif_image_handle_get_list_of_depth_image_IDs(handle, &depth_id, 1); + assert(nDepthImages == 1); + (void) nDepthImages; - struct heif_image_handle* depth_handle; - err = heif_image_handle_get_depth_image_handle(handle, depth_id, &depth_handle); - if (err.code) { - heif_image_handle_release(handle); - std::cerr << "Could not read depth channel\n"; - return 1; - } - - int depth_bit_depth = heif_image_handle_get_luma_bits_per_pixel(depth_handle); - - struct heif_image* depth_image; - err = heif_decode_image(depth_handle, - &depth_image, - encoder->colorspace(false), - encoder->chroma(false, depth_bit_depth), - nullptr); - if (err.code) { - heif_image_handle_release(depth_handle); - heif_image_handle_release(handle); - std::cerr << "Could not decode depth image: " << err.message << "\n"; - return 1; - } - - std::ostringstream s; - s << output_filename.substr(0, output_filename.find('.')); - s << "-depth"; - s << output_filename.substr(output_filename.find('.')); - - written = encoder->Encode(depth_handle, depth_image, s.str()); - if (!written) { - fprintf(stderr, "could not write depth image\n"); - } - else { - if (!option_quiet) { - std::cout << "Depth image written to " << s.str() << "\n"; - } - } - - heif_image_release(depth_image); - heif_image_handle_release(depth_handle); - } - - - // --- aux images - - int nAuxImages = heif_image_handle_get_number_of_auxiliary_images(handle, LIBHEIF_AUX_IMAGE_FILTER_OMIT_ALPHA | LIBHEIF_AUX_IMAGE_FILTER_OMIT_DEPTH); - if (nAuxImages>0) { - - std::vector auxIDs(nAuxImages); - heif_image_handle_get_list_of_auxiliary_image_IDs(handle, - LIBHEIF_AUX_IMAGE_FILTER_OMIT_ALPHA | LIBHEIF_AUX_IMAGE_FILTER_OMIT_DEPTH, - auxIDs.data(), nAuxImages); - - for (heif_item_id auxId : auxIDs) { - - struct heif_image_handle* aux_handle; - err = heif_image_handle_get_auxiliary_image_handle(handle, auxId, &aux_handle); + struct heif_image_handle* depth_handle; + err = heif_image_handle_get_depth_image_handle(handle, depth_id, &depth_handle); if (err.code) { heif_image_handle_release(handle); - std::cerr << "Could not read auxiliary image\n"; + std::cerr << "Could not read depth channel\n"; return 1; } - int aux_bit_depth = heif_image_handle_get_luma_bits_per_pixel(aux_handle); + int depth_bit_depth = heif_image_handle_get_luma_bits_per_pixel(depth_handle); - struct heif_image* aux_image; - err = heif_decode_image(aux_handle, - &aux_image, + struct heif_image* depth_image; + err = heif_decode_image(depth_handle, + &depth_image, encoder->colorspace(false), - encoder->chroma(false, aux_bit_depth), + encoder->chroma(false, depth_bit_depth), nullptr); if (err.code) { - heif_image_handle_release(aux_handle); - heif_image_handle_release(handle); - std::cerr << "Could not decode auxiliary image: " << err.message << "\n"; - return 1; - } - - const char* auxTypeC = nullptr; - err = heif_image_handle_get_auxiliary_type(aux_handle, &auxTypeC); - if (err.code) { - heif_image_handle_release(aux_handle); + heif_image_handle_release(depth_handle); heif_image_handle_release(handle); - std::cerr << "Could not get type of auxiliary image: " << err.message << "\n"; + std::cerr << "Could not decode depth image: " << err.message << "\n"; return 1; } - std::string auxType = std::string(auxTypeC); - - heif_image_handle_free_auxiliary_types(aux_handle, &auxTypeC); - std::ostringstream s; s << output_filename.substr(0, output_filename.find('.')); - s << "-" + auxType; + s << "-depth"; s << output_filename.substr(output_filename.find('.')); - written = encoder->Encode(aux_handle, aux_image, s.str()); + written = encoder->Encode(depth_handle, depth_image, s.str()); if (!written) { - fprintf(stderr, "could not write auxiliary image\n"); + fprintf(stderr, "could not write depth image\n"); } else { if (!option_quiet) { - std::cout << "Auxiliary image written to " << s.str().c_str() << "\n"; + std::cout << "Depth image written to " << s.str() << "\n"; } } - heif_image_release(aux_image); - heif_image_handle_release(aux_handle); + heif_image_release(depth_image); + heif_image_handle_release(depth_handle); } } + // --- aux images + + if (option_aux) { + int nAuxImages = heif_image_handle_get_number_of_auxiliary_images(handle, LIBHEIF_AUX_IMAGE_FILTER_OMIT_ALPHA | LIBHEIF_AUX_IMAGE_FILTER_OMIT_DEPTH); + if (nAuxImages > 0) { + + std::vector auxIDs(nAuxImages); + heif_image_handle_get_list_of_auxiliary_image_IDs(handle, + LIBHEIF_AUX_IMAGE_FILTER_OMIT_ALPHA | LIBHEIF_AUX_IMAGE_FILTER_OMIT_DEPTH, + auxIDs.data(), nAuxImages); + + for (heif_item_id auxId: auxIDs) { + + struct heif_image_handle* aux_handle; + err = heif_image_handle_get_auxiliary_image_handle(handle, auxId, &aux_handle); + if (err.code) { + heif_image_handle_release(handle); + std::cerr << "Could not read auxiliary image\n"; + return 1; + } + + int aux_bit_depth = heif_image_handle_get_luma_bits_per_pixel(aux_handle); + + struct heif_image* aux_image; + err = heif_decode_image(aux_handle, + &aux_image, + encoder->colorspace(false), + encoder->chroma(false, aux_bit_depth), + nullptr); + if (err.code) { + heif_image_handle_release(aux_handle); + heif_image_handle_release(handle); + std::cerr << "Could not decode auxiliary image: " << err.message << "\n"; + return 1; + } + + const char* auxTypeC = nullptr; + err = heif_image_handle_get_auxiliary_type(aux_handle, &auxTypeC); + if (err.code) { + heif_image_handle_release(aux_handle); + heif_image_handle_release(handle); + std::cerr << "Could not get type of auxiliary image: " << err.message << "\n"; + return 1; + } + + std::string auxType = std::string(auxTypeC); + + heif_image_handle_free_auxiliary_types(aux_handle, &auxTypeC); + + std::ostringstream s; + s << output_filename.substr(0, output_filename.find('.')); + s << "-" + auxType; + s << output_filename.substr(output_filename.find('.')); + + written = encoder->Encode(aux_handle, aux_image, s.str()); + if (!written) { + fprintf(stderr, "could not write auxiliary image\n"); + } + else { + if (!option_quiet) { + std::cout << "Auxiliary image written to " << s.str().c_str() << "\n"; + } + } + + heif_image_release(aux_image); + heif_image_handle_release(aux_handle); + } + } + } + heif_image_handle_release(handle); } From 23d87adc0d7059b95e54c38786e4a4b5fd99eee3 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 4 Apr 2022 20:03:09 +0200 Subject: [PATCH 0071/3088] heif-convert: option to replace ':' in output filename --- examples/heif_convert.cc | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/examples/heif_convert.cc b/examples/heif_convert.cc index dbd457d3f9..5d98e02939 100644 --- a/examples/heif_convert.cc +++ b/examples/heif_convert.cc @@ -80,6 +80,7 @@ static void show_help(const char* argv0) " -h, --help show help\n" " -q, --quality quality (for JPEG output)\n" " --with-aux also write auxiliary images (e.g. depth images)\n" + " --no-colons replace ':' characters in auxiliary image filenames with '_'\n" " --quiet do not output status messages to console\n"; } @@ -102,13 +103,15 @@ class ContextReleaser int option_quiet = 0; int option_aux = 0; +int option_no_colons = 0; static struct option long_options[] = { - {(char* const) "quality", required_argument, 0, 'q'}, - {(char* const) "strict", no_argument, 0, 's'}, - {(char* const) "quiet", no_argument, &option_quiet, 1}, - {(char* const) "with-aux", no_argument, &option_aux, 1}, - {(char* const) "help", no_argument, 0, 'h'} + {(char* const) "quality", required_argument, 0, 'q'}, + {(char* const) "strict", no_argument, 0, 's'}, + {(char* const) "quiet", no_argument, &option_quiet, 1}, + {(char* const) "with-aux", no_argument, &option_aux, 1}, + {(char* const) "no-colons", no_argument, &option_no_colons, 1}, + {(char* const) "help", no_argument, 0, 'h'} }; int main(int argc, char** argv) @@ -426,13 +429,19 @@ int main(int argc, char** argv) s << "-" + auxType; s << output_filename.substr(output_filename.find('.')); - written = encoder->Encode(aux_handle, aux_image, s.str()); + std::string auxFilename = s.str(); + + if (option_no_colons) { + std::replace(auxFilename.begin(), auxFilename.end(), ':', '_'); + } + + written = encoder->Encode(aux_handle, aux_image, auxFilename); if (!written) { fprintf(stderr, "could not write auxiliary image\n"); } else { if (!option_quiet) { - std::cout << "Auxiliary image written to " << s.str().c_str() << "\n"; + std::cout << "Auxiliary image written to " << auxFilename << "\n"; } } From 11ffeffadd980f9f96019fe180fc1e81827e3790 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Mon, 4 Apr 2022 20:43:45 +0200 Subject: [PATCH 0072/3088] fix wrong memcpy size --- libheif/heif_colorconversion.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc index 2b05068460..5a07ebb7d4 100644 --- a/libheif/heif_colorconversion.cc +++ b/libheif/heif_colorconversion.cc @@ -526,7 +526,8 @@ Op_YCbCr_to_RGB::convert_colorspace(const std::shared_ptr Date: Tue, 5 Apr 2022 11:44:56 +0200 Subject: [PATCH 0073/3088] CI: compile dav1d with AVX512 --- scripts/install-ci-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install-ci-linux.sh b/scripts/install-ci-linux.sh index cb2aff116d..0ef2cc78f7 100755 --- a/scripts/install-ci-linux.sh +++ b/scripts/install-ci-linux.sh @@ -187,7 +187,7 @@ if [ "$WITH_DAV1D" = "1" ]; then export PATH="$PATH:$HOME/.local/bin" cd third-party - sh dav1d.cmd -Denable_avx512=false + sh dav1d.cmd # dav1d does not support this option anymore: -Denable_avx512=false cd .. fi From 0f8496f22d284e1a69df12fe0b72f375aed31315 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 5 Apr 2022 12:17:59 +0200 Subject: [PATCH 0074/3088] fix dav1d decoding: input stream must be flushed with dav1d 1.0.0 --- libheif/heif_decoder_dav1d.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libheif/heif_decoder_dav1d.cc b/libheif/heif_decoder_dav1d.cc index a6c42e4f87..ecf7382e1a 100644 --- a/libheif/heif_decoder_dav1d.cc +++ b/libheif/heif_decoder_dav1d.cc @@ -163,7 +163,10 @@ struct heif_error dav1d_decode_image(void* decoder_raw, struct heif_image** out_ Dav1dPicture frame; memset(&frame, 0, sizeof(Dav1dPicture)); + bool flushed = false; + for (;;) { + int res = dav1d_send_data(decoder->context, &decoder->data); if ((res < 0) && (res != DAV1D_ERR(EAGAIN))) { err = {heif_error_Decoder_plugin_error, @@ -173,11 +176,11 @@ struct heif_error dav1d_decode_image(void* decoder_raw, struct heif_image** out_ } res = dav1d_get_picture(decoder->context, &frame); - if (res == DAV1D_ERR(EAGAIN)) { - err = {heif_error_Decoder_plugin_error, - heif_suberror_Unspecified, - kEmptyString}; - return err; + if (!flushed && res == DAV1D_ERR(EAGAIN)) { + if (decoder->data.sz == 0) { + flushed = true; + } + continue; } else if (res < 0) { err = {heif_error_Decoder_plugin_error, From 5493f642c83e90b668e56435c2da04582bd9874a Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 11 Apr 2022 09:12:51 +0200 Subject: [PATCH 0075/3088] fuzzing: Add testcase for oss-fuzz issue 13715 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13715 --- ...se-minimized-file-fuzzer-5671864958976000.heic | Bin 0 -> 499 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5671864958976000.heic diff --git a/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5671864958976000.heic b/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5671864958976000.heic new file mode 100644 index 0000000000000000000000000000000000000000..678997e78b2e67e927f7750d80054e60b22106ad GIT binary patch literal 499 zcmZuuJxc>Y5S_ghy+Ra80;xh0Mf?CUVk;b)#>T&(@p4BN?vmv^jdnT3DosR4Cz!(0 zM6eUY!apGB_10FF5tMc2&JznC4D;q=XLjELK-Tt;WX%#LAY5Uu#GEa;mS3S9qEM?k zUQ7X`F#Uw1H;7M2;k!hDp%sPGh{lx-j41`4nf!T7O^kZvLjzD^71=GShu zLaOv;*h8untd&ST^#^I>HjcvP{~vj>GbIL#=f@6oB2`EjM6%%!SA=0$jsB!J%Lb{| m>C5gaZTS5#64g?-_pi;idRA(5yNg_@1*IPky!l literal 0 HcmV?d00001 From ac8b9104652bf1b9bb1b648b53371c2c2762f788 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 11 Apr 2022 09:15:57 +0200 Subject: [PATCH 0076/3088] fuzzing: Add testcase for oss-fuzz issue 39373 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=39373 --- ...ized-color-conversion-fuzzer-6275694804467712 | Bin 0 -> 6620 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fuzzing/corpus/clusterfuzz-testcase-minimized-color-conversion-fuzzer-6275694804467712 diff --git a/fuzzing/corpus/clusterfuzz-testcase-minimized-color-conversion-fuzzer-6275694804467712 b/fuzzing/corpus/clusterfuzz-testcase-minimized-color-conversion-fuzzer-6275694804467712 new file mode 100644 index 0000000000000000000000000000000000000000..f781bfba7d0121caa155c2d967f1ceb397ba9ead GIT binary patch literal 6620 zcmeHLJFdbo5FCdFK}3l}_voGkqTmQ{3JN+7!X@%bat``eQ05F!Qqa`hCY_m)>Zs-$pSNcBj zqD-*uXr@|uuwDoi*+!`=TYIZKr*TseSc%J3?+tjpqGexCxmh9{#DEZ>nsYe#Bm`*V zN28_zHQ*oy1?GLn1!|q!uL~|;2VTf~Y|`mERdC=S1CHD3?aJ{!v<<&5|4*U- literal 0 HcmV?d00001 From c68d2a55643af94553b60d638a8fc42d21d404ca Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 11 Apr 2022 09:17:09 +0200 Subject: [PATCH 0077/3088] fuzzing: Add testcase for oss-fuzz issue 27590 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27590 --- ...-minimized-file-fuzzer-4616081830051840.heic | Bin 0 -> 15792 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-4616081830051840.heic diff --git a/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-4616081830051840.heic b/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-4616081830051840.heic new file mode 100644 index 0000000000000000000000000000000000000000..c95adbc36e215fb9920be055059452565e969652 GIT binary patch literal 15792 zcmeHN4RBP|6+Z9nCfQ9wviT1oKQDh|2_fu;P(m8X<_9GfY(%6H8DZJ{Jtra0%?5+R zNU}*JsMSEM#g?`~5q0VeFw=3MQVeOFMT%39D%L>}#;U+f2SGFq*>~_~S z>=Ph~mTJI8K>o@*L~(67Lu@t(qlzn;utt|g?e~0VcfDpCM_J@9-&^A@%Wzr zf0gS@dK^7^{hSuFpk*5dHl*a(~~x*{e|fFq#m*OM9nuup|qEOq@y02u%x z@^@|IU=F~-dXfJ7bE3J7D%hi{RIIK*HaeV^2L&j>3%tPxRGQ{WR#>TB@U@xYcVgqD_YZ zYhS-XYrdsrxKe;?_$xC>W(#gH6M5pJ7Kzncu^wv1MPYqA?sI5`T;Jo3?Q7(EH}zSz zv;g~jh;_kKX+$1e57yJxxU^UF*42VzUhD#Xg<`E#Wn3>5<3^6XT(#Tn?xQVb_4q#k z3TmYFX0f8uBIKcz%7mh|rt~x+L#Lkyz+^6uynHXok_$gt^1!as_N%P5=`_F{Zz1zH z`}*De7QkK{>ASzLO`8P}h z2k`pDZofPoz^5JHdYj$;{fl<{^_Kt?rvN(FB7*{av14-?RpQ2*H6)b z>y0pQ{+!*;Iw)8VoK*oUq@*3daaZy=8tHPQL&-x!$)^1g%?q@bRgsxdhI6V7_kOO? zRc25-EBfE|JDPj+eQR2#N0*EGFa@R`N5%b4HO(XsGLA=-cQ zazU&X&CR?mD0p>=k-taz>CRMsQBsKFx2g@#JZ(9uT@@Ot`kPYGxFxmQ+dpXA#fFlz z35)&wg`&>wp)H0YrFFIWOyHK|&%Ds$ch=e%(a|7fB$qTCvd)Rs_(c~MH5!}MSs~W8 zSJgt>;((R$_J^943$0oyOWoFX)#%Qy0MqsmYhO${X9lol-@c92O zJQMh2PM7x-@3!pxxX|^@{!vo|i*`XXnK2&Cn8Qk)-P0VCAD0r=ES%ST7ZZ7ITk%1y zHs~>xk0RmzR{zLE{TbNXUAQeg($L=h^mSD67?hMPjm{=0HT3JHAI7m1``b-8cH;bXgJXbqLDnynF&Xne|r~#Htz-izN$zf>$P0gi*{9*vN4Zo~9$r+=Pt3C9HJf=!1m4oH(Y1 zFh-16kY6kdW^EYYI&fSFVRSQC@P6D!gw;+g>>$imO!wm}31g@w;{?npke`1q{swC& zF??nP`6a%KR~v@<4xIEHR{o8FzXK;T*JQ&qz=5YTLubRJz=^*n9PGp?U0C}kCJd|~ zf9)2$+Aw`^;29-^!<;xZ4r?D^FwYA1PrZUy8zveKJo5nINGDEfB0SZJXWdOW%8Aq2 z%50dRu!8*3KO~H)hKy(biExY)>o5St{;^K1pGBChipJ}|CM+<>_+`9_R~sfh4m^h? z5jISL95}OxaH12>Wseci-VGYtwATepV-K}ZM zcXoWyaMy)h58E$wA769oo%U1Z7qrRw3m*TZ`+ePeS66H= zE|4BpCdMZ?4b|0Hf0_$sWAHEF9WDy9Vfs7pJU6Yk{zp#h=)>bpJ&k4kc5xXF0|2k{ zA&xF63nrpPjE`QQjsn4aDl1!;nXStbbn~<4&dt`NR0ZqrkU!7*@^@PQ;GB!Ur!}E( zuGSQ}?sE*F4U-|{snlg;=-U)DFFsuS@-}5}eS|sO3IX|GX*z8hK5!n)$JIN1TMy~^{%R)yToG!QpH+drOD4vgpK4VC8ismR2q`GbYb zF3+c%=8PouoP_X+B#7pYf`nT(e2TUfqnN|C zk<}yhp7t$aPZ-725ufS_4Wk&({^i!NUNC4jdh1%R!44_=%XJWB@}eWR!;iG%O91qt zL6T^)up@t69`?2aoX3m&5|E8%7Cn=tA`BE7(1D-}K|ivP?qE%mC!eH4UEj$lHsf1E zR#@jSaqaiR7RNgVZl&8h23|f#ZTl;-!DvYl%NycxVr_M8d4>ckLjt~m!1orMc~61? zyWq)MeHk9>o8b+%WIKyx<>C#1N7Da8v)afHxJ+c8IdDG*6aoJq-H_4hFZscj(C)Iu7EgSI8S=nSkp?@X98s2!@l~xX=9?T}O}uv=d!m19 zJLsW5Xu4HSm48}J-wLiT<~=9M?8WYn<;A?ahneu$q3>jXO*UESsmFY>xBI;>&4)QM z_2f5W{|1R37f*fzH}vD78(^a*{42R}W#VJk&#}5 Date: Mon, 11 Apr 2022 09:17:58 +0200 Subject: [PATCH 0078/3088] fuzzing: Add testcase for oss-fuzz issue 30239 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30239 --- ...se-minimized-file-fuzzer-5120279175102464.heic | Bin 0 -> 817 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5120279175102464.heic diff --git a/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5120279175102464.heic b/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5120279175102464.heic new file mode 100644 index 0000000000000000000000000000000000000000..0fe029e93e49916b4936c424512355df5907220e GIT binary patch literal 817 zcmcgn%}N6?7@RMA@a9E@qL)uZ^jh%XvD$j@G0JwA23#9tD|qwoLG-GvCZ)CIQf^+XtuJ*VwurAYhK0svR#d4m(->H%NB?+s?KPR6T^#nZ22noOCpR zfr)WfQK5)WNMtlJN+zsxYj5jtCTQ5>Q1Ku=s?+ Date: Mon, 11 Apr 2022 09:18:56 +0200 Subject: [PATCH 0079/3088] fuzzing: Add testcase for oss-fuzz issue 18818 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18818 --- ...e-minimized-file-fuzzer-5643900194127872.heic | Bin 0 -> 1143 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5643900194127872.heic diff --git a/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5643900194127872.heic b/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5643900194127872.heic new file mode 100644 index 0000000000000000000000000000000000000000..b058f402d0cd342260c7c7b4367e160752752e83 GIT binary patch literal 1143 zcmeHFPfHs?6#va`G&$5FsNhLrYHN`o+PknOIan!z;KhT~WwUEWvu3)kqJpL=2qhq* zEqV&nFCcjIV2k7n_$hj;dMIs#nCBY>{RAS259a-T@6XJ8^JV~adf|$y?0uJk=Qc@r z$($=4K=k`=Xd{Ak0NuH4KA;Sdnkhg@CnR>hz61yhn&PFBp%2kI4Z&7I<_ivDK*nNQ zR7d!@v73m_-RJd6%6Sh(U`^+Du;Cg>W^Cn_oIz$dkSb7&+fq3N#zhXK13s-}$gCau zv!8T>l^${Y#fq Date: Mon, 11 Apr 2022 09:19:41 +0200 Subject: [PATCH 0080/3088] fuzzing: Add testcase for oss-fuzz issue 31352 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=31352 --- ...-minimized-file-fuzzer-5752063708495872.heic | Bin 0 -> 16389 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5752063708495872.heic diff --git a/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5752063708495872.heic b/fuzzing/corpus/clusterfuzz-testcase-minimized-file-fuzzer-5752063708495872.heic new file mode 100644 index 0000000000000000000000000000000000000000..0c6b1985b65ab663ea6c3971539504bd8b57a708 GIT binary patch literal 16389 zcmeGi33L=yvig{ro?J7zL&(v&NC*LDk{|(rgd_@4)Odgad75Ez4dxh!py0AHIgr5m zAOuuUbO*_zJb8lq_W9)D;t<0d#0&5Ml=Wa)5OIAGL;+!E>;In4B&2~vxx(`&U0qfG z=>LCL)vu}^0Ej57oolTqwU_}*l?C(?9voR!T5BRaEb$d3l{SL>ikH=5t_21WH!brC z9}-I})n#~(DzTN4J1L}%-)vi@=)nW5mf9-B0n!2Zu@up8{|8|z2)c6h-n1)cqkcbXXMlMN%Qr0WUUJRboY0m_1<=hm`_P5 z&J^G*UZrNMtrjgU+46+PYOMrsLOjHVlR|to!OIb+j{^vsA@SR3oBQs`!#4X67tIwW z9D_N9c-o9E{PHfi=egJfeDf`{td*v@Vj(g3eJej-s(Eec99#!LUX69G%~D=bD~`uq zDisT=&BM~fbc1mu0NHbCoD+A`y=21P_wpLP0vP)?9%);=yxZOecpZECZ1(a}vH$|n zr0>{lHQ7vbymM|hux0q3kG~AyKNTQ&7xsBzR#^rfbXXX_TmaRVZube)Y0YwgbIoq| zuP?dX=hgyn2LPPaC?k0&@p%k~A_SXgw`m=4_S`AlUSH0E^9|2o{1~^JG~h@Jj{Hxv zCawX7Iho7Qo?R*&JPY=sg`2}0$EBPQA~GX$jtcYcKCCxXWY+D`pIZCASiH-^wZ`sP=(V)LYc>2dA{x8Bu0|Dop( zzLm6Xke_&5@80-O^1lZOAF!HejisS`we=+|YO=b|Ft|vDMU~ z{D9tSnPb5_aDsqd&egG5qpqOMLS;kMfRO9JW|3{ZXt|~~i@beBo0XYKC;c03)|g({ ztT7j|Sz{bNf-WrXhg-hUEgsXR_E$HL&W#P3+vpeRFV=Q7V;(DYa8qM+ZftUBqxhZv zbacegm4#bVQUV_rG+g}TCclUT<2Uend;ZF>h@9nhS%ZD-En43BpSIZEn~L7s!JY=` z*xq+fEj@N(-u;blCT?qt$&EdE?9kZ@=)d{G`aj!d5%p(#Z)N*nRC-vb9y2`m`04Dx z@F!{(cRb6lG&Jn!i|ssbu+Tf4cKdp;U(9APIVgG^c%5gKm~q5*Qn4hiA;UG))dNc* zM@f0Rdm`Gs~g@Y(erZ9!V!4#%aIE2D93WriSjKbj*8Ynb! z`~o$ks}?qC7hpgNdP|83og^0x!6gOjV==x&8jl$d{W+zzGA*v5G?_7N zA6G$XbhRWp9%BmZkAbs?CQjjAbe}zR!Uu@B(AD?Qi7ODQ0 z&_mv$bc9T&HBcJkUM$#u=xvn7kXNFIk(s$LK#}Qvl#Y_=;eVwx#<*CpzX2UkY>(ls zL}z2PhBTQKtvCKeX_1hmefk!>yD;eS&>8iVj+g1o0!k;y^a!$ZE)0)I!Tuxm;{9_B zmOS)LuOs5Z(8)uOoI`1hSg~OHtZYiB$n+>8DJ~4MNWuD1E?AyP48NYA8MKF-jAurgZi=N*hUAdJ(=ra#L84 z7o3ata?}u+UJsylBEeKqeL@V zH|~iq+dnnzIWuih!7j1&yMJYJ%^KB0tL7g`=^akVs#6YoHyE3gz+)Kr&>MT7$r z@giGE??&S=+(?YOvPK&+M;o$4!>G|CMvOM%?u+%$$@5@ut$(2tzq2XcJEx{(3D@ib zXvUxk$K?&_>BeSGo*z4_7z&WF1X5rqd90*cj2egIpetM znXMUgJ}3q1#jTkXPedHIlNK^Oc|MUD6^W3~e^VcR^r36}M{V8T9_Y{@YZjoUV2*=7 z?RI~O3d`l;7-R7g@uF+ee5E=ftXHK=QMl!5!CGQ*eiCcol1Ho|@xpjCn$ZarJ(*@Uc;w&Bq zavKIsyNs*RY|A)cp2&+w%6rPafte%9Cn|(y*4qXrFvD7DnN@2r+!e@T3d#p71)Q?F z%O6SokQ9|K{ze5{vZp*7j^6jZOF}+&t+nCBeuxd7mxS@}4&2Dbh3K z{-iIdm0Eb~$+P9rz4hKSn_Mr~N&V$|d35jC%Jn?Y6C2d|d}$v9T)jYdM5(`;)=In6 zeTGu+uIrQ5@HvhzwUpM^eSf59cN+R{7$ajeX z)=!p}PtbhvDz!$KTvll+pEdbWQ|0W^sXSC+_RdsUI=R$ZW3JFM=#o6}#&Jh#aL~=q z?L-L{0>h(|hYrso8i<7&4uTMg>{_zj?*A>tgZ5X{vey7UaJk*b%Q0hxUwo>_F>1%Y zFO%s#GIE5Wn)IZ)jCXRzNIFY25)UN2RNc=2afZqKuvjwNR4JNGRi!qQm|0aNmJK%! z%fiN3-oazC(f9t%8>X#T5p~4q=zdlnONsyD0I)MU&&$WrU5KCQ@SK_I4%BGoo)*u! zNwi&fb_cs|`|h1~LinTb13?=;i>0DvQJc0$cJ9&4O6Hz8LU)_<4OA`)= zLUVovx)O_g#O*o2#cuLXUEl=O9#J>5!4BepAPqVZrBg_M{C@!-bzLlD*$xhGZ zkGDbI_mvSU@)h*bf|co*P>a%bfj9E$nQ1-rgT0daF|S|g#|@(9S8f@9mjaaDs(Bg> zR)|WRXLN5^iyn6Y#lt|ZhvHr6V4B}Y8}hr4p=&Ye%X*ro_rWPJa?RbH0tNBBDn7x5 zbmKQXJoAm_rYASwbtw672a1-qXez76O8&|Bj!o1-5w`534vKESo;oP^zGWvK3Zr_M zEFSo&=oegl2L+#e1^lc}ySa-u^+7T)#nN3e99K&;G}HM*f2t0hK4a>yC#wqoyeIaH z=;bllQFDaY9N&j<76NgFuZ0bc1*c)mUrvU$DD~4M8sP4pcz^esvq&2jIzx|LW&f9l<@uh;b39;XWa`^&4rryp7P)rRMO{%qO$noa+H1wzK6tGmUX;}?{J zV$JM;JDqR|Un=`z;cdn>a}uvJZ9)5XBc(=rf0A6+8Q#mjjQ-%+M)vtY?0+8&`onwp zo&FX5xkIn~tG<4|F`~^^PB?8BulLjZ%72Br7U{n~a+duvXL-YaA-(M9=WmY0E@OK5 zGJLP@564g6-GH)-dHUBb9ehbozdyW Date: Mon, 11 Apr 2022 09:23:32 +0200 Subject: [PATCH 0081/3088] CI: Update which corpus files to process per fuzzer. --- scripts/run-ci.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/run-ci.sh b/scripts/run-ci.sh index 49211c2296..2113f03714 100755 --- a/scripts/run-ci.sh +++ b/scripts/run-ci.sh @@ -261,7 +261,8 @@ if [ ! -z "$TARBALL" ]; then fi if [ ! -z "$FUZZER" ] && [ "$CURRENT_OS" = "linux" ]; then - ./libheif/file-fuzzer ./fuzzing/corpus/* + ./libheif/color-conversion-fuzzer ./fuzzing/corpus/*color-conversion-fuzzer* + ./libheif/file-fuzzer ./fuzzing/corpus/*.heic echo "Running color conversion fuzzer ..." ./libheif/color-conversion-fuzzer -max_total_time=120 From 18eba31aac124d8cf67c1df2f0fd26db63140474 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 11 Apr 2022 09:28:26 +0200 Subject: [PATCH 0082/3088] Don't check clusterfuzz testcases for licenses. --- scripts/check-licenses.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-licenses.sh b/scripts/check-licenses.sh index 486cee70b2..70227e125a 100755 --- a/scripts/check-licenses.sh +++ b/scripts/check-licenses.sh @@ -21,7 +21,7 @@ set -eu # echo "Checking licenses..." -CHECK_RESULT=`/usr/bin/licensecheck --recursive --ignore 'emscripten|libde265|README\.md|post\.js|/.git/' .` +CHECK_RESULT=`/usr/bin/licensecheck --recursive --ignore 'emscripten|libde265|README\.md|post\.js|/.git/|clusterfuzz-testcase-.*' .` FOUND= while read -r line; do From d35d018909f59fa5ac7659fa12799fc62b3e1b6a Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 11 Apr 2022 09:31:55 +0200 Subject: [PATCH 0083/3088] CI: Install libde265 from git for fuzzing. --- .github/workflows/fuzzer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fuzzer.yml b/.github/workflows/fuzzer.yml index 3d7f37aa4e..0a243b4f23 100644 --- a/.github/workflows/fuzzer.yml +++ b/.github/workflows/fuzzer.yml @@ -11,7 +11,7 @@ jobs: env: WITH_AOM: 1 WITH_GRAPHICS: 1 - WITH_LIBDE265: 1 + WITH_LIBDE265: 2 WITH_X265: 1 FUZZER: 1 runs-on: ubuntu-18.04 From a0ee6cee127f16581c4abe53cf0539f65b795a1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 13:41:41 +0000 Subject: [PATCH 0084/3088] Bump actions/setup-go from 2 to 3 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 3. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c60117e6ce..e9834ced18 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: go-version: "1.10" From a7ba323d6d364ee2364d9492907b959815c6504e Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Tue, 31 May 2022 22:37:38 +0200 Subject: [PATCH 0085/3088] Added extra check to prevent recursion that could result in a stack overflow. --- libheif/heif_context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_context.cc b/libheif/heif_context.cc index e13fc2739f..d752396583 100644 --- a/libheif/heif_context.cc +++ b/libheif/heif_context.cc @@ -963,7 +963,7 @@ Error HeifContext::get_id_of_non_virtual_child_image(heif_item_id id, heif_item_ // TODO: check whether this really can be recursive (e.g. overlay of grid images) - if (image_references.empty()) { + if (image_references.empty() || image_references[0] == id) { return Error(heif_error_Invalid_input, heif_suberror_No_item_data, "Derived image does not reference any other image items"); From 49f98aee27391f96865dd05262d78d8bf0031a38 Mon Sep 17 00:00:00 2001 From: H1Gdev Date: Thu, 30 Jun 2022 14:13:24 +0900 Subject: [PATCH 0086/3088] Update README.md. - Add libtool to macOS install dependencies. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f598894ea..abd5d8bf0f 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ For AVIF support, make sure that libaom is installed. 1. Install dependencies with Homebrew ``` - brew install automake make pkg-config x265 libde265 libjpeg + brew install automake make pkg-config x265 libde265 libjpeg libtool ``` From debd678d116c70eb3d5495c0c36de28e1bdb6b5a Mon Sep 17 00:00:00 2001 From: "L. E. Segovia" Date: Mon, 18 Jul 2022 21:26:17 -0300 Subject: [PATCH 0087/3088] Fix ASAN alloc-dealloc-mismatch for ColorProfile_nclx Fixes #652 --- libheif/heif_cxx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_cxx.h b/libheif/heif_cxx.h index 269541f7f3..7a1665ebd3 100644 --- a/libheif/heif_cxx.h +++ b/libheif/heif_cxx.h @@ -791,7 +791,7 @@ namespace heif { inline ColorProfile_nclx::~ColorProfile_nclx() { - delete mProfile; + heif_nclx_color_profile_free(mProfile); } inline heif_color_primaries ColorProfile_nclx::get_color_primaries() const From 24219638a252d55560726bf1105116633bd1a5cd Mon Sep 17 00:00:00 2001 From: Stepka Date: Mon, 1 Aug 2022 13:03:29 +0300 Subject: [PATCH 0088/3088] API to deinitialize encders and decoders plugins --- libheif/heif.cc | 20 ++++++++++++++++++-- libheif/heif.h | 4 ++++ libheif/heif_plugin_registry.cc | 14 +------------- libheif/heif_plugin_registry.h | 13 ++++++++++++- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/libheif/heif.cc b/libheif/heif.cc index 239ebdcdd9..3cc5286dcb 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -1617,7 +1617,6 @@ struct heif_error heif_register_decoder_plugin(const heif_decoder_plugin* decode return error_Ok; } - struct heif_error heif_register_encoder_plugin(const heif_encoder_plugin* encoder_plugin) { if (!encoder_plugin) { @@ -1631,8 +1630,25 @@ struct heif_error heif_register_encoder_plugin(const heif_encoder_plugin* encode return error_Ok; } +void heif_unregister_decoder_plugins() +{ + for( const auto* plugin : heif::s_decoder_plugins ) { + if( plugin->deinit_plugin ) { + (*plugin->deinit_plugin)(); + } + } + heif::s_decoder_plugins.clear(); +} - +void heif_unregister_encoder_plugins() +{ + for( const auto& plugin : heif::s_encoder_descriptors ) { + if( plugin->plugin->cleanup_plugin ) { + (*plugin->plugin->cleanup_plugin)(); + } + } + heif::s_encoder_descriptors.clear(); +} /* int heif_image_get_number_of_data_chunks(heif_image* img); diff --git a/libheif/heif.h b/libheif/heif.h index b5624523d6..5446229735 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -1474,7 +1474,11 @@ struct heif_error heif_register_decoder_plugin(const struct heif_decoder_plugin* LIBHEIF_API struct heif_error heif_register_encoder_plugin(const struct heif_encoder_plugin*); +LIBHEIF_API +void heif_unregister_encoder_plugins(); +LIBHEIF_API +void heif_unregister_decoder_plugins(); // DEPRECATED, typo in function name LIBHEIF_API diff --git a/libheif/heif_plugin_registry.cc b/libheif/heif_plugin_registry.cc index 15a7cf7c9e..34f1d8ef40 100644 --- a/libheif/heif_plugin_registry.cc +++ b/libheif/heif_plugin_registry.cc @@ -57,20 +57,8 @@ using namespace heif; std::set heif::s_decoder_plugins; - -struct encoder_descriptor_priority_order -{ - bool operator()(const std::unique_ptr& a, - const std::unique_ptr& b) const - { - return a->plugin->priority > b->plugin->priority; // highest priority first - } -}; - - std::set, - encoder_descriptor_priority_order> s_encoder_descriptors; - + encoder_descriptor_priority_order> heif::s_encoder_descriptors; static class Register_Default_Plugins { diff --git a/libheif/heif_plugin_registry.h b/libheif/heif_plugin_registry.h index 6c70d49907..b7c70fc99d 100644 --- a/libheif/heif_plugin_registry.h +++ b/libheif/heif_plugin_registry.h @@ -44,11 +44,22 @@ struct heif_encoder_descriptor { return plugin->compression_format; } }; +struct encoder_descriptor_priority_order +{ + bool operator()(const std::unique_ptr& a, + const std::unique_ptr& b) const + { + return a->plugin->priority > b->plugin->priority; // highest priority first + } +}; -namespace heif { +namespace heif { extern std::set s_decoder_plugins; + extern std::set, + encoder_descriptor_priority_order> s_encoder_descriptors; + void register_decoder(const heif_decoder_plugin* decoder_plugin); void register_encoder(const heif_encoder_plugin* encoder_plugin); From a50ef159794ff66fc0a03d5269b1c36a000673ea Mon Sep 17 00:00:00 2001 From: Sam James Date: Tue, 16 Aug 2022 02:23:13 +0100 Subject: [PATCH 0089/3088] configure.ac: fix bashism configure scripts need to be runnable with a POSIX-compliant /bin/sh. On many (but not all!) systems, /bin/sh is provided by Bash, so errors like this aren't spotted. Notably Debian defaults to /bin/sh provided by dash which doesn't tolerate such bashisms as '=='. This retains compatibility with bash. Fixes errors/warnings like: ``` checking for pthread_create in -lpthread... yes checking for simple visibility declarations... yes /var/tmp/portage/media-libs/libheif-1.12.0-r2/work/libheif-1.12.0/configure: 18821: test: x: unexpected operator checking pkg-config is at least version 0.9.0... yes checking for aom... yes ``` Signed-off-by: Sam James --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f4f7a2a130..2f539bde9a 100644 --- a/configure.ac +++ b/configure.ac @@ -85,7 +85,7 @@ AS_IF([test "x$enable_tests" = "xyes"], [ HAVE_VISIBILITY=0 CFLAG_VISIBILITY= ]) -AM_CONDITIONAL([HAVE_TESTS], [test "x$HAVE_TESTS" == "x1"]) +AM_CONDITIONAL([HAVE_TESTS], [test "x$HAVE_TESTS" = "x1"]) AM_CONDITIONAL([HAVE_VISIBILITY], [test "x$HAVE_VISIBILITY" != "x0"]) if eval "test x$enable_visibility = x" ; then enable_visibility=yes ; fi From 32fd0f04696406a86d69c944bbb577d586732667 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 19 Aug 2022 08:26:51 +0200 Subject: [PATCH 0090/3088] go: Use native runtime.KeepAlive. --- go/Makefile.am | 4 +- go/heif/heif.go | 86 ++++++++++++++++++++--------------------- go/heif/keepalive_16.go | 30 -------------- go/heif/keepalive_17.go | 31 --------------- 4 files changed, 44 insertions(+), 107 deletions(-) delete mode 100644 go/heif/keepalive_16.go delete mode 100644 go/heif/keepalive_17.go diff --git a/go/Makefile.am b/go/Makefile.am index 329261e457..2fd8766f2e 100644 --- a/go/Makefile.am +++ b/go/Makefile.am @@ -1,8 +1,6 @@ EXTRA_DIST = \ heif/heif.go \ - heif/heif_test.go \ - heif/keepalive_16.go \ - heif/keepalive_17.go + heif/heif_test.go gopath: ln -sf ${CURDIR} ${CURDIR}/src diff --git a/go/heif/heif.go b/go/heif/heif.go index bfe41543bb..31dc954668 100644 --- a/go/heif/heif.go +++ b/go/heif/heif.go @@ -356,14 +356,14 @@ func (c *Context) ReadFromFile(filename string) error { defer C.free(unsafe.Pointer(c_filename)) err := C.heif_context_read_from_file(c.context, c_filename, nil) - keepAlive(c) + runtime.KeepAlive(c) return convertHeifError(err) } func (c *Context) ReadFromMemory(data []byte) error { // TODO: Use reader API internally. err := C.heif_context_read_from_memory(c.context, unsafe.Pointer(&data[0]), C.size_t(len(data)), nil) - keepAlive(c) + runtime.KeepAlive(c) return convertHeifError(err) } @@ -383,19 +383,19 @@ func (e *Encoder) Name() string { func (e *Encoder) SetQuality(q int) error { err := C.heif_encoder_set_lossy_quality(e.encoder, C.int(q)) - keepAlive(e) + runtime.KeepAlive(e) return convertHeifError(err) } func (e *Encoder) SetLossless(l LosslessMode) error { err := C.heif_encoder_set_lossless(e.encoder, C.int(l)) - keepAlive(e) + runtime.KeepAlive(e) return convertHeifError(err) } func (e *Encoder) SetLoggingLevel(l LoggingLevel) error { err := C.heif_encoder_set_logging_level(e.encoder, C.int(l)) - keepAlive(e) + runtime.KeepAlive(e) return convertHeifError(err) } @@ -412,7 +412,7 @@ func (c *Context) convertEncoderDescriptor(d *C.struct_heif_encoder_descriptor) name: C.GoString(cname), } err := C.heif_context_get_encoder(c.context, d, &enc.encoder) - keepAlive(c) + runtime.KeepAlive(c) if err := convertHeifError(err); err != nil { return nil, err } @@ -424,7 +424,7 @@ func (c *Context) NewEncoder(compression Compression) (*Encoder, error) { const max = 1 descriptors := make([]*C.struct_heif_encoder_descriptor, max) num := int(C.heif_context_get_encoder_descriptors(c.context, uint32(compression), nil, &descriptors[0], C.int(max))) - keepAlive(c) + runtime.KeepAlive(c) if num == 0 { return nil, fmt.Errorf("no encoder for compression %v", compression) } @@ -433,39 +433,39 @@ func (c *Context) NewEncoder(compression Compression) (*Encoder, error) { func (c *Context) WriteToFile(filename string) error { err := C.heif_context_write_to_file(c.context, C.CString(filename)) - keepAlive(c) + runtime.KeepAlive(c) return convertHeifError(err) } func (c *Context) GetNumberOfTopLevelImages() int { i := int(C.heif_context_get_number_of_top_level_images(c.context)) - keepAlive(c) + runtime.KeepAlive(c) return i } func (c *Context) IsTopLevelImageID(ID int) bool { ok := C.heif_context_is_top_level_image_ID(c.context, C.heif_item_id(ID)) != 0 - keepAlive(c) + runtime.KeepAlive(c) return ok } func (c *Context) GetListOfTopLevelImageIDs() []int { num := int(C.heif_context_get_number_of_top_level_images(c.context)) - keepAlive(c) + runtime.KeepAlive(c) if num == 0 { return []int{} } origIDs := make([]C.heif_item_id, num) C.heif_context_get_list_of_top_level_image_IDs(c.context, &origIDs[0], C.int(num)) - keepAlive(c) + runtime.KeepAlive(c) return convertItemIDs(origIDs, num) } func (c *Context) GetPrimaryImageID() (int, error) { var id C.heif_item_id err := C.heif_context_get_primary_image_ID(c.context, &id) - keepAlive(c) + runtime.KeepAlive(c) if err := convertHeifError(err); err != nil { return 0, err } @@ -486,7 +486,7 @@ func freeHeifImageHandle(c *ImageHandle) { func (c *Context) GetPrimaryImageHandle() (*ImageHandle, error) { var handle ImageHandle err := C.heif_context_get_primary_image_handle(c.context, &handle.handle) - keepAlive(c) + runtime.KeepAlive(c) if err := convertHeifError(err); err != nil { return nil, err } @@ -497,7 +497,7 @@ func (c *Context) GetPrimaryImageHandle() (*ImageHandle, error) { func (c *Context) GetImageHandle(id int) (*ImageHandle, error) { var handle ImageHandle err := C.heif_context_get_image_handle(c.context, C.heif_item_id(id), &handle.handle) - keepAlive(c) + runtime.KeepAlive(c) if err := convertHeifError(err); err != nil { return nil, err } @@ -507,57 +507,57 @@ func (c *Context) GetImageHandle(id int) (*ImageHandle, error) { func (h *ImageHandle) IsPrimaryImage() bool { ok := C.heif_image_handle_is_primary_image(h.handle) != 0 - keepAlive(h) + runtime.KeepAlive(h) return ok } func (h *ImageHandle) GetWidth() int { i := int(C.heif_image_handle_get_width(h.handle)) - keepAlive(h) + runtime.KeepAlive(h) return i } func (h *ImageHandle) GetHeight() int { i := int(C.heif_image_handle_get_height(h.handle)) - keepAlive(h) + runtime.KeepAlive(h) return i } func (h *ImageHandle) HasAlphaChannel() bool { ok := C.heif_image_handle_has_alpha_channel(h.handle) != 0 - keepAlive(h) + runtime.KeepAlive(h) return ok } func (h *ImageHandle) HasDepthImage() bool { ok := C.heif_image_handle_has_depth_image(h.handle) != 0 - keepAlive(h) + runtime.KeepAlive(h) return ok } func (h *ImageHandle) GetNumberOfDepthImages() int { i := int(C.heif_image_handle_get_number_of_depth_images(h.handle)) - keepAlive(h) + runtime.KeepAlive(h) return i } func (h *ImageHandle) GetListOfDepthImageIDs() []int { num := int(C.heif_image_handle_get_number_of_depth_images(h.handle)) - keepAlive(h) + runtime.KeepAlive(h) if num == 0 { return []int{} } origIDs := make([]C.heif_item_id, num) C.heif_image_handle_get_list_of_depth_image_IDs(h.handle, &origIDs[0], C.int(num)) - keepAlive(h) + runtime.KeepAlive(h) return convertItemIDs(origIDs, num) } func (h *ImageHandle) GetDepthImageHandle(depth_image_id int) (*ImageHandle, error) { var handle ImageHandle err := C.heif_image_handle_get_depth_image_handle(h.handle, C.heif_item_id(depth_image_id), &handle.handle) - keepAlive(h) + runtime.KeepAlive(h) if err := convertHeifError(err); err != nil { return nil, err } @@ -568,27 +568,27 @@ func (h *ImageHandle) GetDepthImageHandle(depth_image_id int) (*ImageHandle, err func (h *ImageHandle) GetNumberOfThumbnails() int { i := int(C.heif_image_handle_get_number_of_thumbnails(h.handle)) - keepAlive(h) + runtime.KeepAlive(h) return i } func (h *ImageHandle) GetListOfThumbnailIDs() []int { num := int(C.heif_image_handle_get_number_of_thumbnails(h.handle)) - keepAlive(h) + runtime.KeepAlive(h) if num == 0 { return []int{} } origIDs := make([]C.heif_item_id, num) C.heif_image_handle_get_list_of_thumbnail_IDs(h.handle, &origIDs[0], C.int(num)) - keepAlive(h) + runtime.KeepAlive(h) return convertItemIDs(origIDs, num) } func (h *ImageHandle) GetThumbnail(thumbnail_id int) (*ImageHandle, error) { var handle ImageHandle err := C.heif_image_handle_get_thumbnail(h.handle, C.heif_item_id(thumbnail_id), &handle.handle) - keepAlive(h) + runtime.KeepAlive(h) runtime.SetFinalizer(&handle, freeHeifImageHandle) return &handle, convertHeifError(err) } @@ -646,7 +646,7 @@ func (h *ImageHandle) DecodeImage(colorspace Colorspace, chroma Chroma, options } err := C.heif_decode_image(h.handle, &image.image, uint32(colorspace), uint32(chroma), opt) - keepAlive(h) + runtime.KeepAlive(h) if err := convertHeifError(err); err != nil { return nil, err } @@ -657,37 +657,37 @@ func (h *ImageHandle) DecodeImage(colorspace Colorspace, chroma Chroma, options func (img *Image) GetColorspace() Colorspace { cs := Colorspace(C.heif_image_get_colorspace(img.image)) - keepAlive(img) + runtime.KeepAlive(img) return cs } func (img *Image) GetChromaFormat() Chroma { c := Chroma(C.heif_image_get_chroma_format(img.image)) - keepAlive(img) + runtime.KeepAlive(img) return c } func (img *Image) GetWidth(channel Channel) int { i := int(C.heif_image_get_width(img.image, uint32(channel))) - keepAlive(img) + runtime.KeepAlive(img) return i } func (img *Image) GetHeight(channel Channel) int { i := int(C.heif_image_get_height(img.image, uint32(channel))) - keepAlive(img) + runtime.KeepAlive(img) return i } func (img *Image) GetBitsPerPixel(channel Channel) int { i := int(C.heif_image_get_bits_per_pixel(img.image, uint32(channel))) - keepAlive(img) + runtime.KeepAlive(img) return i } func (img *Image) GetBitsPerPixelRange(channel Channel) int { i := int(C.heif_image_get_bits_per_pixel_range(img.image, uint32(channel))) - keepAlive(img) + runtime.KeepAlive(img) return i } @@ -1075,14 +1075,14 @@ func (i *ImageAccess) setData(data []byte, stride int) { func (img *Image) GetPlane(channel Channel) (*ImageAccess, error) { height := C.heif_image_get_height(img.image, uint32(channel)) - keepAlive(img) + runtime.KeepAlive(img) if height == -1 { return nil, fmt.Errorf("No such channel %v", channel) } var stride C.int plane := C.heif_image_get_plane(img.image, uint32(channel), &stride) - keepAlive(img) + runtime.KeepAlive(img) if plane == nil { return nil, fmt.Errorf("No such channel %v", channel) } @@ -1101,7 +1101,7 @@ func (img *Image) GetPlane(channel Channel) (*ImageAccess, error) { func (img *Image) NewPlane(channel Channel, width, height, depth int) (*ImageAccess, error) { err := C.heif_image_add_plane(img.image, uint32(channel), C.int(width), C.int(height), C.int(depth)) - keepAlive(img) + runtime.KeepAlive(img) if err := convertHeifError(err); err != nil { return nil, err } @@ -1111,7 +1111,7 @@ func (img *Image) NewPlane(channel Channel, width, height, depth int) (*ImageAcc func (img *Image) ScaleImage(width int, height int) (*Image, error) { var scaled_image Image err := C.heif_image_scale_image(img.image, &scaled_image.image, C.int(width), C.int(height), nil) - keepAlive(img) + runtime.KeepAlive(img) if err := convertHeifError(err); err != nil { return nil, err } @@ -1336,10 +1336,10 @@ func EncodeFromImage(img image.Image, compression Compression, quality int, loss var handle ImageHandle err2 := C.heif_context_encode_image(ctx.context, out.image, enc.encoder, encOpts.options, &handle.handle) - keepAlive(ctx) - keepAlive(out) - keepAlive(enc) - keepAlive(encOpts) + runtime.KeepAlive(ctx) + runtime.KeepAlive(out) + runtime.KeepAlive(enc) + runtime.KeepAlive(encOpts) if err := convertHeifError(err2); err != nil { return nil, fmt.Errorf("failed to encode image: %v", err) } diff --git a/go/heif/keepalive_16.go b/go/heif/keepalive_16.go deleted file mode 100644 index ef6941d5e4..0000000000 --- a/go/heif/keepalive_16.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build !go1.7 - -/* - * GO interface to libheif - * Copyright (c) 2019 struktur AG, Dirk Farin - * - * This file is part of heif, an example application using libheif. - * - * heif is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * heif is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with heif. If not, see . - */ - -package heif - -//go:noinline -func keepAlive(x interface{}) { - if _Cgo_always_false { - _Cgo_use(x) - } -} diff --git a/go/heif/keepalive_17.go b/go/heif/keepalive_17.go deleted file mode 100644 index d5b5d85a27..0000000000 --- a/go/heif/keepalive_17.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build go1.7 - -/* - * GO interface to libheif - * Copyright (c) 2019 struktur AG, Dirk Farin - * - * This file is part of heif, an example application using libheif. - * - * heif is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * heif is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with heif. If not, see . - */ - -package heif - -import ( - "runtime" -) - -func keepAlive(x interface{}) { - runtime.KeepAlive(x) -} From fac14ccf741f5fef560d50e5ea924ea74d6d7029 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 19 Aug 2022 08:44:54 +0200 Subject: [PATCH 0091/3088] CI: Fix installation of wine32 after GitHub image updates. --- scripts/install-ci-linux.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/install-ci-linux.sh b/scripts/install-ci-linux.sh index 0ef2cc78f7..6309a6fa65 100755 --- a/scripts/install-ci-linux.sh +++ b/scripts/install-ci-linux.sh @@ -110,8 +110,11 @@ fi if [ "$MINGW" == "32" ]; then sudo dpkg --add-architecture i386 - # https://github.com/actions/virtual-environments/issues/4589 - sudo apt install -y --allow-downgrades libpcre2-8-0=10.34-7 + # https://github.com/actions/runner-images/issues/4589 + sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list + sudo apt-get update + sudo apt-get install -y --allow-downgrades libgd3/focal libpcre2-8-0/focal libpcre2-16-0/focal libpcre2-32-0/focal libpcre2-posix2/focal + sudo apt-get purge -y libmono* moby* mono* php* libgdiplus libpcre2-posix3 libzip4 INSTALL_PACKAGES="$INSTALL_PACKAGES \ binutils-mingw-w64-i686 \ g++-mingw-w64-i686 \ @@ -120,7 +123,6 @@ if [ "$MINGW" == "32" ]; then wine-stable \ wine32 \ " - UPDATE_APT=1 elif [ "$MINGW" == "64" ]; then INSTALL_PACKAGES="$INSTALL_PACKAGES \ binutils-mingw-w64-x86-64 \ From d607771742fd7dd44e8cc5637348abb800fe116a Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Fri, 19 Aug 2022 08:26:20 +0200 Subject: [PATCH 0092/3088] Added missing return value check that could cause an access violation because the output plane was not allocated. --- libheif/heif_colorconversion.cc | 130 ++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 40 deletions(-) diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc index 5a07ebb7d4..3b90885a57 100644 --- a/libheif/heif_colorconversion.cc +++ b/libheif/heif_colorconversion.cc @@ -245,7 +245,9 @@ Op_RGB_to_RGB24_32::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, want_alpha ? heif_chroma_interleaved_32bit : heif_chroma_interleaved_24bit); - outimg->add_plane(heif_channel_interleaved, width, height, 8); + if (!outimg->add_plane(heif_channel_interleaved, width, height, 8)) { + return nullptr; + } const uint8_t* in_r, * in_g, * in_b, * in_a = nullptr; int in_r_stride = 0, in_g_stride = 0, in_b_stride = 0, in_a_stride = 0; @@ -418,12 +420,16 @@ Op_YCbCr_to_RGB::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, heif_chroma_444); - outimg->add_plane(heif_channel_R, width, height, bpp_y); - outimg->add_plane(heif_channel_G, width, height, bpp_y); - outimg->add_plane(heif_channel_B, width, height, bpp_y); + if (!outimg->add_plane(heif_channel_R, width, height, bpp_y) || + !outimg->add_plane(heif_channel_G, width, height, bpp_y) || + !outimg->add_plane(heif_channel_B, width, height, bpp_y)) { + return nullptr; + } if (has_alpha) { - outimg->add_plane(heif_channel_Alpha, width, height, bpp_a); + if (!outimg->add_plane(heif_channel_Alpha, width, height, bpp_a)) { + return nullptr; + } } const Pixel* in_y, * in_cb, * in_cr, * in_a; @@ -621,12 +627,16 @@ Op_RGB_to_YCbCr::convert_colorspace(const std::shared_ptradd_plane(heif_channel_Y, width, height, bpp); - outimg->add_plane(heif_channel_Cb, cwidth, cheight, bpp); - outimg->add_plane(heif_channel_Cr, cwidth, cheight, bpp); + if (!outimg->add_plane(heif_channel_Y, width, height, bpp) || + !outimg->add_plane(heif_channel_Cb, cwidth, cheight, bpp) || + !outimg->add_plane(heif_channel_Cr, cwidth, cheight, bpp)) { + return nullptr; + } if (has_alpha) { - outimg->add_plane(heif_channel_Alpha, width, height, bpp); + if (!outimg->add_plane(heif_channel_Alpha, width, height, bpp)) { + return nullptr; + } } const Pixel* in_r, * in_g, * in_b, * in_a; @@ -848,7 +858,9 @@ Op_YCbCr420_to_RGB24::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, heif_chroma_interleaved_24bit); - outimg->add_plane(heif_channel_interleaved, width, height, 8); + if (!outimg->add_plane(heif_channel_interleaved, width, height, 8)) { + return nullptr; + } auto colorProfile = input->get_color_profile_nclx(); YCbCr_to_RGB_coefficients coeffs = YCbCr_to_RGB_coefficients::defaults(); @@ -966,7 +978,9 @@ Op_YCbCr420_to_RGB32::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, heif_chroma_interleaved_32bit); - outimg->add_plane(heif_channel_interleaved, width, height, 8); + if (!outimg->add_plane(heif_channel_interleaved, width, height, 8)) { + return nullptr; + } // --- get conversion coefficients @@ -1125,7 +1139,9 @@ Op_RGB_HDR_to_RRGGBBaa_BE::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, output_has_alpha ? heif_chroma_interleaved_RRGGBBAA_BE : heif_chroma_interleaved_RRGGBB_BE); - outimg->add_plane(heif_channel_interleaved, width, height, input->get_bits_per_pixel(heif_channel_R)); + if (!outimg->add_plane(heif_channel_interleaved, width, height, input->get_bits_per_pixel(heif_channel_R))) { + return nullptr; + } const uint16_t* in_r, * in_g, * in_b, * in_a = nullptr; int in_r_stride = 0, in_g_stride = 0, in_b_stride = 0, in_a_stride = 0; @@ -1283,7 +1299,9 @@ Op_RGB_to_RRGGBBaa_BE::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, output_has_alpha ? heif_chroma_interleaved_RRGGBBAA_BE : heif_chroma_interleaved_RRGGBB_BE); - outimg->add_plane(heif_channel_interleaved, width, height, input->get_bits_per_pixel(heif_channel_R)); + if (!outimg->add_plane(heif_channel_interleaved, width, height, input->get_bits_per_pixel(heif_channel_R))) { + return nullptr; + } const uint8_t* in_r, * in_g, * in_b, * in_a = nullptr; int in_r_stride = 0, in_g_stride = 0, in_b_stride = 0, in_a_stride = 0; @@ -1404,12 +1422,16 @@ Op_RRGGBBaa_BE_to_RGB_HDR::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, heif_chroma_444); - outimg->add_plane(heif_channel_R, width, height, input->get_bits_per_pixel(heif_channel_interleaved)); - outimg->add_plane(heif_channel_G, width, height, input->get_bits_per_pixel(heif_channel_interleaved)); - outimg->add_plane(heif_channel_B, width, height, input->get_bits_per_pixel(heif_channel_interleaved)); + if (!outimg->add_plane(heif_channel_R, width, height, input->get_bits_per_pixel(heif_channel_interleaved)) || + !outimg->add_plane(heif_channel_G, width, height, input->get_bits_per_pixel(heif_channel_interleaved)) || + !outimg->add_plane(heif_channel_B, width, height, input->get_bits_per_pixel(heif_channel_interleaved))) { + return nullptr; + } if (has_alpha) { - outimg->add_plane(heif_channel_Alpha, width, height, input->get_bits_per_pixel(heif_channel_interleaved)); + if (!outimg->add_plane(heif_channel_Alpha, width, height, input->get_bits_per_pixel(heif_channel_interleaved))) { + return nullptr; + } } const uint8_t* in_p; @@ -1573,8 +1595,10 @@ Op_RRGGBBaa_swap_endianness::convert_colorspace(const std::shared_ptradd_plane(heif_channel_interleaved, width, height, - input->get_bits_per_pixel(heif_channel_interleaved)); + if (!outimg->add_plane(heif_channel_interleaved, width, height, + input->get_bits_per_pixel(heif_channel_interleaved))) { + return nullptr; + } const uint8_t* in_p = nullptr; int in_p_stride = 0; @@ -1663,15 +1687,19 @@ Op_mono_to_YCbCr420::convert_colorspace(const std::shared_ptradd_plane(heif_channel_Y, width, height, input_bpp); - outimg->add_plane(heif_channel_Cb, chroma_width, chroma_height, input_bpp); - outimg->add_plane(heif_channel_Cr, chroma_width, chroma_height, input_bpp); + if (!outimg->add_plane(heif_channel_Y, width, height, input_bpp) || + !outimg->add_plane(heif_channel_Cb, chroma_width, chroma_height, input_bpp) || + !outimg->add_plane(heif_channel_Cr, chroma_width, chroma_height, input_bpp)) { + return nullptr; + } int alpha_bpp = 0; bool has_alpha = input->has_channel(heif_channel_Alpha); if (has_alpha) { alpha_bpp = input->get_bits_per_pixel(heif_channel_Alpha); - outimg->add_plane(heif_channel_Alpha, width, height, alpha_bpp); + if (!outimg->add_plane(heif_channel_Alpha, width, height, alpha_bpp)) { + return nullptr; + } } @@ -1834,7 +1862,9 @@ Op_mono_to_RGB24_32::convert_colorspace(const std::shared_ptrcreate(width, height, heif_colorspace_RGB, heif_chroma_interleaved_24bit); } - outimg->add_plane(heif_channel_interleaved, width, height, 8); + if (!outimg->add_plane(heif_channel_interleaved, width, height, 8)) { + return nullptr; + } const uint8_t* in_y, * in_a; int in_y_stride = 0, in_a_stride; @@ -2009,12 +2039,16 @@ Op_RGB24_32_to_YCbCr::convert_colorspace(const std::shared_ptrget_chroma_format() == heif_chroma_interleaved_32bit); - outimg->add_plane(heif_channel_Y, width, height, 8); - outimg->add_plane(heif_channel_Cb, chroma_width, chroma_height, 8); - outimg->add_plane(heif_channel_Cr, chroma_width, chroma_height, 8); + if (!outimg->add_plane(heif_channel_Y, width, height, 8) || + !outimg->add_plane(heif_channel_Cb, chroma_width, chroma_height, 8) || + !outimg->add_plane(heif_channel_Cr, chroma_width, chroma_height, 8)) { + return nullptr; + } if (has_alpha) { - outimg->add_plane(heif_channel_Alpha, width, height, 8); + if (!outimg->add_plane(heif_channel_Alpha, width, height, 8)) { + return nullptr; + } } uint8_t* out_cb, * out_cr, * out_y, * out_a; @@ -2308,12 +2342,16 @@ Op_RGB24_32_to_YCbCr444_GBR::convert_colorspace(const std::shared_ptrget_chroma_format() == heif_chroma_interleaved_32bit); - outimg->add_plane(heif_channel_Y, width, height, 8); - outimg->add_plane(heif_channel_Cb, width, height, 8); - outimg->add_plane(heif_channel_Cr, width, height, 8); + if (!outimg->add_plane(heif_channel_Y, width, height, 8) || + !outimg->add_plane(heif_channel_Cb, width, height, 8) || + !outimg->add_plane(heif_channel_Cr, width, height, 8)) { + return nullptr; + } if (has_alpha) { - outimg->add_plane(heif_channel_Alpha, width, height, 8); + if (!outimg->add_plane(heif_channel_Alpha, width, height, 8)) { + return nullptr; + } } uint8_t* out_cb, * out_cr, * out_y, * out_a; @@ -2518,7 +2556,9 @@ Op_to_hdr_planes::convert_colorspace(const std::shared_ptr if (input->has_channel(channel)) { int width = input->get_width(channel); int height = input->get_height(channel); - outimg->add_plane(channel, width, height, target_state.bits_per_pixel); + if (outimg->add_plane(channel, width, height, target_state.bits_per_pixel)) { + return nullptr; + } int input_bits = input->get_bits_per_pixel(channel); int output_bits = target_state.bits_per_pixel; @@ -2619,7 +2659,9 @@ Op_to_sdr_planes::convert_colorspace(const std::shared_ptr if (input_bits > 8) { int width = input->get_width(channel); int height = input->get_height(channel); - outimg->add_plane(channel, width, height, 8); + if (!outimg->add_plane(channel, width, height, 8)) { + return nullptr; + } int shift = input_bits - 8; @@ -2730,12 +2772,16 @@ Op_RRGGBBxx_HDR_to_YCbCr420::convert_colorspace(const std::shared_ptradd_plane(heif_channel_Y, width, height, bpp); - outimg->add_plane(heif_channel_Cb, cwidth, cheight, bpp); - outimg->add_plane(heif_channel_Cr, cwidth, cheight, bpp); + if (!outimg->add_plane(heif_channel_Y, width, height, bpp) || + !outimg->add_plane(heif_channel_Cb, cwidth, cheight, bpp) || + !outimg->add_plane(heif_channel_Cr, cwidth, cheight, bpp)) { + return nullptr; + } if (has_alpha) { - outimg->add_plane(heif_channel_Alpha, width, height, bpp); + if (!outimg->add_plane(heif_channel_Alpha, width, height, bpp)) { + return nullptr; + } } const uint8_t* in_p; @@ -2929,10 +2975,14 @@ Op_YCbCr420_to_RRGGBBaa::convert_colorspace(const std::shared_ptradd_plane(heif_channel_interleaved, width, height, bpp); + if (!outimg->add_plane(heif_channel_interleaved, width, height, bpp)) { + return nullptr; + } if (has_alpha) { - outimg->add_plane(heif_channel_Alpha, width, height, bpp); + if (!outimg->add_plane(heif_channel_Alpha, width, height, bpp)) { + return nullptr; + } } uint8_t* out_p; From 09dfb9efa4c787465277978736c73005f1019a47 Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Fri, 19 Aug 2022 17:21:46 +0200 Subject: [PATCH 0093/3088] Minor change to the unit tests. --- go/heif/heif_test.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/go/heif/heif_test.go b/go/heif/heif_test.go index 8771db0eed..3cded0446b 100644 --- a/go/heif/heif_test.go +++ b/go/heif/heif_test.go @@ -65,14 +65,8 @@ func CheckHeifImage(t *testing.T, handle *ImageHandle, thumbnail bool) { } } - if img, err := handle.DecodeImage(ColorspaceUndefined, ChromaUndefined, nil); err != nil { - t.Errorf("Could not decode image: %s", err) - } else { - img.GetColorspace() - img.GetChromaFormat() - } - decodeTests := []decodeTest{ + decodeTest{ColorspaceUndefined, ChromaUndefined}, decodeTest{ColorspaceYCbCr, Chroma420}, decodeTest{ColorspaceYCbCr, Chroma422}, decodeTest{ColorspaceYCbCr, Chroma444}, From bc011d32ffb67a3c9b94ae433d73765174c114e3 Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Fri, 19 Aug 2022 17:21:56 +0200 Subject: [PATCH 0094/3088] Corrected return value check. --- libheif/heif_colorconversion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc index 3b90885a57..f021e4b8bb 100644 --- a/libheif/heif_colorconversion.cc +++ b/libheif/heif_colorconversion.cc @@ -2556,7 +2556,7 @@ Op_to_hdr_planes::convert_colorspace(const std::shared_ptr if (input->has_channel(channel)) { int width = input->get_width(channel); int height = input->get_height(channel); - if (outimg->add_plane(channel, width, height, target_state.bits_per_pixel)) { + if (!outimg->add_plane(channel, width, height, target_state.bits_per_pixel)) { return nullptr; } From 9d07c39dc660d8151b5e4ea36d13331eaf896902 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 17:41:46 +0200 Subject: [PATCH 0095/3088] fix local variable name shadowing --- examples/heif_enc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index aef563eb82..170b2d6b36 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -957,9 +957,9 @@ void list_encoder_parameters(heif_encoder* encoder) if (valid_options) { std::cerr << ", { "; - for (int i = 0; valid_options[i]; i++) { - if (i > 0) { std::cerr << ","; } - std::cerr << valid_options[i]; + for (int k = 0; valid_options[k]; k++) { + if (k > 0) { std::cerr << ","; } + std::cerr << valid_options[k]; } std::cerr << " }"; } From e042cfad8974fea767aace51bc26982c6f60562f Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 18:04:50 +0200 Subject: [PATCH 0096/3088] fix heif-plugin version numbers --- libheif/heif.cc | 6 +++--- libheif/heif_plugin.h | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libheif/heif.cc b/libheif/heif.cc index 3cc5286dcb..d84a80ca81 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -1595,7 +1595,7 @@ struct heif_error heif_register_decoder(heif_context* heif, const heif_decoder_p if (!decoder_plugin) { return error_null_parameter; } - else if (decoder_plugin->plugin_api_version != 1) { + else if (decoder_plugin->plugin_api_version > 2) { return error_unsupported_plugin_version; } @@ -1609,7 +1609,7 @@ struct heif_error heif_register_decoder_plugin(const heif_decoder_plugin* decode if (!decoder_plugin) { return error_null_parameter; } - else if (decoder_plugin->plugin_api_version != 1) { + else if (decoder_plugin->plugin_api_version > 2) { return error_unsupported_plugin_version; } @@ -1622,7 +1622,7 @@ struct heif_error heif_register_encoder_plugin(const heif_encoder_plugin* encode if (!encoder_plugin) { return error_null_parameter; } - else if (encoder_plugin->plugin_api_version != 1) { + else if (encoder_plugin->plugin_api_version > 3) { return error_unsupported_plugin_version; } diff --git a/libheif/heif_plugin.h b/libheif/heif_plugin.h index 5b64be2c19..46a06df19b 100644 --- a/libheif/heif_plugin.h +++ b/libheif/heif_plugin.h @@ -40,7 +40,7 @@ extern "C" { // 1.1 1 1 1 // 1.4 1 1 2 // 1.8 1 2 2 -// 1.13 2 2 2 +// 1.13 2 3 2 // ==================================================================================================== @@ -51,8 +51,8 @@ extern "C" { struct heif_decoder_plugin { - // API version supported by this plugin - int plugin_api_version; // current version: 1 + // API version supported by this plugin (see table above for supported versions) + int plugin_api_version; // --- version 1 functions --- @@ -127,8 +127,8 @@ enum heif_image_input_class struct heif_encoder_plugin { - // API version supported by this plugin - int plugin_api_version; // current version: 2 + // API version supported by this plugin (see table above for supported versions) + int plugin_api_version; // --- version 1 functions --- From 45a8fd2d8dee777bfb777ef265813dce22bee8f3 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 18:16:00 +0200 Subject: [PATCH 0097/3088] move comparator 'encoder_descriptor_priority_order' into heif namespace --- libheif/heif_plugin_registry.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libheif/heif_plugin_registry.h b/libheif/heif_plugin_registry.h index b7c70fc99d..78f85ec489 100644 --- a/libheif/heif_plugin_registry.h +++ b/libheif/heif_plugin_registry.h @@ -44,17 +44,18 @@ struct heif_encoder_descriptor { return plugin->compression_format; } }; -struct encoder_descriptor_priority_order -{ - bool operator()(const std::unique_ptr& a, - const std::unique_ptr& b) const + +namespace heif { + struct encoder_descriptor_priority_order { - return a->plugin->priority > b->plugin->priority; // highest priority first - } -}; + bool operator()(const std::unique_ptr& a, + const std::unique_ptr& b) const + { + return a->plugin->priority > b->plugin->priority; // highest priority first + } + }; -namespace heif { extern std::set s_decoder_plugins; extern std::set, From 6d15810ebebfceff1d5599368f7219c14c0f874e Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 19:47:47 +0200 Subject: [PATCH 0098/3088] heif_init() / heif_deinit() for proper initialization and cleanup --- examples/heif_convert.cc | 11 +++++ examples/heif_enc.cc | 10 ++++ examples/heif_info.cc | 11 +++++ libheif/CMakeLists.txt | 1 + libheif/heif.cc | 19 ------- libheif/heif.h | 30 +++++++++--- libheif/heif_init.cpp | 87 +++++++++++++++++++++++++++++++++ libheif/heif_init.h | 32 ++++++++++++ libheif/heif_plugin_registry.cc | 20 +++----- libheif/heif_plugin_registry.h | 2 + 10 files changed, 186 insertions(+), 37 deletions(-) create mode 100644 libheif/heif_init.cpp create mode 100644 libheif/heif_init.h diff --git a/examples/heif_convert.cc b/examples/heif_convert.cc index 5d98e02939..da564f97a4 100644 --- a/examples/heif_convert.cc +++ b/examples/heif_convert.cc @@ -114,8 +114,19 @@ static struct option long_options[] = { {(char* const) "help", no_argument, 0, 'h'} }; + +class LibHeifInitializer { +public: + LibHeifInitializer() { heif_init(nullptr); } + ~LibHeifInitializer() { heif_deinit(); } +}; + + int main(int argc, char** argv) { + // This takes care of initializing libheif and also deinitializing it at the end to free all resources. + LibHeifInitializer initializer; + int quality = -1; // Use default quality. bool strict_decoding = false; diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 170b2d6b36..01dc6cd36a 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -1006,8 +1006,18 @@ static void show_list_of_encoders(const heif_encoder_descriptor*const* encoder_d } +class LibHeifInitializer { +public: + LibHeifInitializer() { heif_init(nullptr); } + ~LibHeifInitializer() { heif_deinit(); } +}; + + int main(int argc, char** argv) { + // This takes care of initializing libheif and also deinitializing it at the end to free all resources. + LibHeifInitializer initializer; + int quality = 50; bool lossless = false; std::string output_filename; diff --git a/examples/heif_info.cc b/examples/heif_info.cc index 56c55b86fb..6234d81f22 100644 --- a/examples/heif_info.cc +++ b/examples/heif_info.cc @@ -95,8 +95,19 @@ void show_help(const char* argv0) fprintf(stderr, " -h, --help show help\n"); } + +class LibHeifInitializer { +public: + LibHeifInitializer() { heif_init(nullptr); } + ~LibHeifInitializer() { heif_deinit(); } +}; + + int main(int argc, char** argv) { + // This takes care of initializing libheif and also deinitializing it at the end to free all resources. + LibHeifInitializer initializer; + bool dump_boxes = false; bool write_raw_image = false; diff --git a/libheif/CMakeLists.txt b/libheif/CMakeLists.txt index 761271fe3f..e3c354bd43 100644 --- a/libheif/CMakeLists.txt +++ b/libheif/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(heif heif_colorconversion.h heif_plugin_registry.h heif_limits.h + heif_init.cpp heif_init.h nclx.h logging.h ${libheif_headers} diff --git a/libheif/heif.cc b/libheif/heif.cc index d84a80ca81..35f7f432bd 100644 --- a/libheif/heif.cc +++ b/libheif/heif.cc @@ -1630,25 +1630,6 @@ struct heif_error heif_register_encoder_plugin(const heif_encoder_plugin* encode return error_Ok; } -void heif_unregister_decoder_plugins() -{ - for( const auto* plugin : heif::s_decoder_plugins ) { - if( plugin->deinit_plugin ) { - (*plugin->deinit_plugin)(); - } - } - heif::s_decoder_plugins.clear(); -} - -void heif_unregister_encoder_plugins() -{ - for( const auto& plugin : heif::s_encoder_descriptors ) { - if( plugin->plugin->cleanup_plugin ) { - (*plugin->plugin->cleanup_plugin)(); - } - } - heif::s_encoder_descriptors.clear(); -} /* int heif_image_get_number_of_data_chunks(heif_image* img); diff --git a/libheif/heif.h b/libheif/heif.h index 5446229735..464581f8f2 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -291,6 +291,30 @@ typedef uint32_t heif_item_id; +// ========================= library initialization ====================== + +// You should call heif_init() when you start using libheif and heif_deinit() when you are finished. +// These calls are reference counted. Each call to heif_init() should be matched by one call to heif_deinit(). +// For backwards compatibility, it is not really necessary to call heif_init(), but if you don't, the plugins +// registered by default may not be freed correctly. +// However, this should not be mixed, i.e. one part of your program does use heif_init()/heif_deinit() and another doesn't. +// If in doubt, enclose everything with init/deinit. + +struct heif_init_params { + int version; + + // currently no parameters +}; + + +// You may pass nullptr to get default parameters. Currently, no parameters are supported. +LIBHEIF_API +struct heif_error heif_init(struct heif_init_params*); + +LIBHEIF_API +void heif_deinit(); + + // ========================= file type check ====================== enum heif_filetype_result @@ -1474,12 +1498,6 @@ struct heif_error heif_register_decoder_plugin(const struct heif_decoder_plugin* LIBHEIF_API struct heif_error heif_register_encoder_plugin(const struct heif_encoder_plugin*); -LIBHEIF_API -void heif_unregister_encoder_plugins(); - -LIBHEIF_API -void heif_unregister_decoder_plugins(); - // DEPRECATED, typo in function name LIBHEIF_API int heif_encoder_descriptor_supportes_lossy_compression(const struct heif_encoder_descriptor*); diff --git a/libheif/heif_init.cpp b/libheif/heif_init.cpp new file mode 100644 index 0000000000..a0ea37fb89 --- /dev/null +++ b/libheif/heif_init.cpp @@ -0,0 +1,87 @@ +/* + * HEIF codec. + * Copyright (c) 2022 Dirk Farin + * + * This file is part of libheif. + * + * libheif is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * libheif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libheif. If not, see . + */ + +#include "heif_init.h" +#include "heif.h" +#include "error.h" +#include "heif_plugin_registry.h" + +using namespace heif; + + +static int heif_library_initialization_count = 0; +static bool default_plugins_registered = true; // because they are implicitly registered at startup + + +struct heif_error heif_init(struct heif_init_params*) +{ + if (heif_library_initialization_count == 0 && !default_plugins_registered) { + register_default_plugins(); + } + + heif_library_initialization_count++; + + return {heif_error_Ok, heif_suberror_Unspecified, Error::kSuccess}; +} + + +static void heif_unregister_decoder_plugins() +{ + for( const auto* plugin : heif::s_decoder_plugins ) { + if( plugin->deinit_plugin ) { + (*plugin->deinit_plugin)(); + } + } + heif::s_decoder_plugins.clear(); +} + +static void heif_unregister_encoder_plugins() +{ + for( const auto& plugin : heif::s_encoder_descriptors ) { + if( plugin->plugin->cleanup_plugin ) { + (*plugin->plugin->cleanup_plugin)(); + } + } + heif::s_encoder_descriptors.clear(); +} + +void heif_deinit() +{ + if (heif_library_initialization_count==0) { + return; + } + + heif_library_initialization_count--; + if (heif_library_initialization_count == 0) { + heif_unregister_decoder_plugins(); + heif_unregister_encoder_plugins(); + default_plugins_registered = false; + } +} + + +static class Register_Default_Plugins +{ +public: + Register_Default_Plugins() + { + register_default_plugins(); + } +} dummy; diff --git a/libheif/heif_init.h b/libheif/heif_init.h new file mode 100644 index 0000000000..dfb07d592e --- /dev/null +++ b/libheif/heif_init.h @@ -0,0 +1,32 @@ +/* + * HEIF codec. + * Copyright (c) 2022 Dirk Farin + * + * This file is part of libheif. + * + * libheif is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * libheif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libheif. If not, see . + */ + + +#ifndef LIBHEIF_HEIF_INIT_H +#define LIBHEIF_HEIF_INIT_H + +namespace heif { + // TODO: later, we might defer the default plugin initialization to when they are actually used for the first time. + // That would prevent them from being initialized every time at program start, even when the application software uses heif_init() later on. + + // void implicit_plugin_registration(); +} + +#endif //LIBHEIF_HEIF_INIT_H diff --git a/libheif/heif_plugin_registry.cc b/libheif/heif_plugin_registry.cc index 34f1d8ef40..4555c68f81 100644 --- a/libheif/heif_plugin_registry.cc +++ b/libheif/heif_plugin_registry.cc @@ -60,36 +60,32 @@ std::set heif::s_decoder_plugins; std::set, encoder_descriptor_priority_order> heif::s_encoder_descriptors; -static class Register_Default_Plugins +void heif::register_default_plugins() { -public: - Register_Default_Plugins() - { #if HAVE_LIBDE265 - heif::register_decoder(get_decoder_plugin_libde265()); + heif::register_decoder(get_decoder_plugin_libde265()); #endif #if HAVE_X265 - heif::register_encoder(get_encoder_plugin_x265()); + heif::register_encoder(get_encoder_plugin_x265()); #endif #if HAVE_AOM_ENCODER - heif::register_encoder(get_encoder_plugin_aom()); + heif::register_encoder(get_encoder_plugin_aom()); #endif #if HAVE_AOM_DECODER - heif::register_decoder(get_decoder_plugin_aom()); + heif::register_decoder(get_decoder_plugin_aom()); #endif #if HAVE_RAV1E - heif::register_encoder(get_encoder_plugin_rav1e()); + heif::register_encoder(get_encoder_plugin_rav1e()); #endif #if HAVE_DAV1D - heif::register_decoder(get_decoder_plugin_dav1d()); + heif::register_decoder(get_decoder_plugin_dav1d()); #endif - } -} dummy; +} void heif::register_decoder(const heif_decoder_plugin* decoder_plugin) diff --git a/libheif/heif_plugin_registry.h b/libheif/heif_plugin_registry.h index 78f85ec489..2aa2055e4c 100644 --- a/libheif/heif_plugin_registry.h +++ b/libheif/heif_plugin_registry.h @@ -61,6 +61,8 @@ namespace heif { extern std::set, encoder_descriptor_priority_order> s_encoder_descriptors; + void register_default_plugins(); + void register_decoder(const heif_decoder_plugin* decoder_plugin); void register_encoder(const heif_encoder_plugin* encoder_plugin); From f6a071942fad2873156db856beece57f5b76ef27 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 19:52:13 +0200 Subject: [PATCH 0099/3088] add heif_init.h/cc to Makefile.am --- libheif/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libheif/Makefile.am b/libheif/Makefile.am index eabc60ee5c..41ca80d623 100644 --- a/libheif/Makefile.am +++ b/libheif/Makefile.am @@ -67,6 +67,8 @@ libheif_la_SOURCES = \ heif_context.cc \ heif_hevc.h \ heif_hevc.cc \ + heif_init.h \ + heif_init.cc \ heif_avif.h \ heif_avif.cc \ heif_plugin_registry.h \ From ffeb8276b7b9471bcefb5d3cef9388b8e47a4de7 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 20:09:41 +0200 Subject: [PATCH 0100/3088] workaround for msys/win32 linking problem (see PR#634) --- libheif/heif_encoder_x265.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libheif/heif_encoder_x265.cc b/libheif/heif_encoder_x265.cc index 3cfa296dfc..789b13ec9c 100644 --- a/libheif/heif_encoder_x265.cc +++ b/libheif/heif_encoder_x265.cc @@ -187,7 +187,8 @@ static const char* x265_plugin_name() { strcpy(plugin_name, "x265 HEVC encoder"); - const char* x265_version = (x265_version_str != nullptr ? x265_version_str : "null"); + const x265_api* api = x265_api_get(0); + const char* x265_version = ((api != nullptr && api->version_str != nullptr) ? api->version_str : "null"); if (strlen(x265_version) + strlen(plugin_name) + 4 < MAX_PLUGIN_NAME_LENGTH) { strcat(plugin_name, " ("); From 7fc94279b283d81a058c0fe8944846a78d79a06a Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 20:14:29 +0200 Subject: [PATCH 0101/3088] renamed heif_init.cpp to heif_init.cc to match the convention --- libheif/CMakeLists.txt | 2 +- libheif/{heif_init.cpp => heif_init.cc} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename libheif/{heif_init.cpp => heif_init.cc} (100%) diff --git a/libheif/CMakeLists.txt b/libheif/CMakeLists.txt index e3c354bd43..9444891ff8 100644 --- a/libheif/CMakeLists.txt +++ b/libheif/CMakeLists.txt @@ -34,7 +34,7 @@ add_library(heif heif_colorconversion.h heif_plugin_registry.h heif_limits.h - heif_init.cpp heif_init.h + heif_init.cc heif_init.h nclx.h logging.h ${libheif_headers} diff --git a/libheif/heif_init.cpp b/libheif/heif_init.cc similarity index 100% rename from libheif/heif_init.cpp rename to libheif/heif_init.cc From ba1547b9e4c4cb244b8c91b4fcc6f132318123db Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 22:34:23 +0200 Subject: [PATCH 0102/3088] cast to match integer types --- libheif/box.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libheif/box.cc b/libheif/box.cc index f48d781f08..dacdf7ad1f 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -61,8 +61,8 @@ Fraction::Fraction(int32_t num, int32_t den) Fraction::Fraction(uint32_t num, uint32_t den) { - assert(num <= std::numeric_limits::max()); - assert(den <= std::numeric_limits::max()); + assert(num <= (uint32_t)std::numeric_limits::max()); + assert(den <= (uint32_t)std::numeric_limits::max()); *this = Fraction(int32_t(num), int32_t(den)); } @@ -2331,14 +2331,14 @@ Error Box_clap::parse(BitstreamRange& range) uint32_t vertical_offset_num = range.read32(); uint32_t vertical_offset_den = range.read32(); - if (clean_aperture_width_num > std::numeric_limits::max() || - clean_aperture_width_den > std::numeric_limits::max() || - clean_aperture_height_num > std::numeric_limits::max() || - clean_aperture_height_den > std::numeric_limits::max() || - horizontal_offset_num > std::numeric_limits::max() || - horizontal_offset_den > std::numeric_limits::max() || - vertical_offset_num > std::numeric_limits::max() || - vertical_offset_den > std::numeric_limits::max()) { + if (clean_aperture_width_num > (uint32_t)std::numeric_limits::max() || + clean_aperture_width_den > (uint32_t)std::numeric_limits::max() || + clean_aperture_height_num > (uint32_t)std::numeric_limits::max() || + clean_aperture_height_den > (uint32_t)std::numeric_limits::max() || + horizontal_offset_num > (uint32_t)std::numeric_limits::max() || + horizontal_offset_den > (uint32_t)std::numeric_limits::max() || + vertical_offset_num > (uint32_t)std::numeric_limits::max() || + vertical_offset_den > (uint32_t)std::numeric_limits::max()) { return Error(heif_error_Invalid_input, heif_suberror_Invalid_fractional_number, "Exceeded supported value range."); From 626b6203f1d033f9e8bcacd610baf7cbe775ce82 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Tue, 30 Aug 2022 23:07:45 +0200 Subject: [PATCH 0103/3088] fix integer types for 'clap' box --- libheif/box.cc | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/libheif/box.cc b/libheif/box.cc index dacdf7ad1f..b82610c78c 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -2326,18 +2326,19 @@ Error Box_clap::parse(BitstreamRange& range) uint32_t clean_aperture_width_den = range.read32(); uint32_t clean_aperture_height_num = range.read32(); uint32_t clean_aperture_height_den = range.read32(); - uint32_t horizontal_offset_num = range.read32(); - uint32_t horizontal_offset_den = range.read32(); - uint32_t vertical_offset_num = range.read32(); - uint32_t vertical_offset_den = range.read32(); - - if (clean_aperture_width_num > (uint32_t)std::numeric_limits::max() || - clean_aperture_width_den > (uint32_t)std::numeric_limits::max() || - clean_aperture_height_num > (uint32_t)std::numeric_limits::max() || - clean_aperture_height_den > (uint32_t)std::numeric_limits::max() || - horizontal_offset_num > (uint32_t)std::numeric_limits::max() || + + // Note: in the standard document 14496-12(2015), it says that the offset values should also be unsigned integers, + // but this is obviously an error. Even the accompanying standard text says that offsets may be negative. + int32_t horizontal_offset_num = (int32_t) range.read32(); + uint32_t horizontal_offset_den = (int32_t)range.read32(); + int32_t vertical_offset_num = (int32_t) range.read32(); + uint32_t vertical_offset_den = (int32_t)range.read32(); + + if (clean_aperture_width_num > (uint32_t) std::numeric_limits::max() || + clean_aperture_width_den > (uint32_t) std::numeric_limits::max() || + clean_aperture_height_num > (uint32_t) std::numeric_limits::max() || + clean_aperture_height_den > (uint32_t) std::numeric_limits::max() || horizontal_offset_den > (uint32_t)std::numeric_limits::max() || - vertical_offset_num > (uint32_t)std::numeric_limits::max() || vertical_offset_den > (uint32_t)std::numeric_limits::max()) { return Error(heif_error_Invalid_input, heif_suberror_Invalid_fractional_number, @@ -2348,8 +2349,8 @@ Error Box_clap::parse(BitstreamRange& range) clean_aperture_width_den); m_clean_aperture_height = Fraction(clean_aperture_height_num, clean_aperture_height_den); - m_horizontal_offset = Fraction(horizontal_offset_num, horizontal_offset_den); - m_vertical_offset = Fraction(vertical_offset_num, vertical_offset_den); + m_horizontal_offset = Fraction(horizontal_offset_num, (int32_t)horizontal_offset_den); + m_vertical_offset = Fraction(vertical_offset_num, (int32_t)vertical_offset_den); if (!m_clean_aperture_width.is_valid() || !m_clean_aperture_height.is_valid() || !m_horizontal_offset.is_valid() || !m_vertical_offset.is_valid()) { return Error(heif_error_Invalid_input, From e995017a20d862e1d61a36cb5cfc7371231cdb2d Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Wed, 31 Aug 2022 14:17:29 +0200 Subject: [PATCH 0104/3088] move Register_Default_Plugins back to heif_plugin_registry.cc (#668) --- examples/heif_enc.cc | 2 +- libheif/heif_init.cc | 9 --------- libheif/heif_plugin_registry.cc | 12 ++++++++++++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 01dc6cd36a..0d827d50df 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -1016,7 +1016,7 @@ class LibHeifInitializer { int main(int argc, char** argv) { // This takes care of initializing libheif and also deinitializing it at the end to free all resources. - LibHeifInitializer initializer; + //LibHeifInitializer initializer; int quality = 50; bool lossless = false; diff --git a/libheif/heif_init.cc b/libheif/heif_init.cc index a0ea37fb89..6701aed985 100644 --- a/libheif/heif_init.cc +++ b/libheif/heif_init.cc @@ -76,12 +76,3 @@ void heif_deinit() } } - -static class Register_Default_Plugins -{ -public: - Register_Default_Plugins() - { - register_default_plugins(); - } -} dummy; diff --git a/libheif/heif_plugin_registry.cc b/libheif/heif_plugin_registry.cc index 4555c68f81..09106cc84a 100644 --- a/libheif/heif_plugin_registry.cc +++ b/libheif/heif_plugin_registry.cc @@ -60,6 +60,18 @@ std::set heif::s_decoder_plugins; std::set, encoder_descriptor_priority_order> heif::s_encoder_descriptors; +// Note: we cannot move this to 'heif_init' because we have to make sure that this is initialized +// AFTER the two global std::set above. +static class Register_Default_Plugins +{ +public: + Register_Default_Plugins() + { + register_default_plugins(); + } +} dummy; + + void heif::register_default_plugins() { #if HAVE_LIBDE265 From 0020008c23cb3e221bbd27e224da9410c153b6dc Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Wed, 31 Aug 2022 14:18:26 +0200 Subject: [PATCH 0105/3088] fix chroma plane height for alpha image in rav1e encoder plugin (#554) --- libheif/heif_encoder_rav1e.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/libheif/heif_encoder_rav1e.cc b/libheif/heif_encoder_rav1e.cc index ed7befd3f8..5d4370bc6d 100644 --- a/libheif/heif_encoder_rav1e.cc +++ b/libheif/heif_encoder_rav1e.cc @@ -521,6 +521,7 @@ struct heif_error rav1e_encode_image(void* encoder_raw, const struct heif_image* if (input_class == heif_image_input_class_alpha) { chromaSampling = RA_CHROMA_SAMPLING_CS420; // I can't seem to get RA_CHROMA_SAMPLING_CS400 to work right now, unfortunately chromaPosition = RA_CHROMA_SAMPLE_POSITION_UNKNOWN; // TODO: set to CENTER when AV1 and rav1e supports this + yShift = 1; } else { switch (chroma) { From a80bcc517dd83366f020de9edbf6bf7a7eaef3c0 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Wed, 31 Aug 2022 14:48:28 +0200 Subject: [PATCH 0106/3088] enable libheif initialization again in heif-enc --- examples/heif_enc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc index 0d827d50df..01dc6cd36a 100644 --- a/examples/heif_enc.cc +++ b/examples/heif_enc.cc @@ -1016,7 +1016,7 @@ class LibHeifInitializer { int main(int argc, char** argv) { // This takes care of initializing libheif and also deinitializing it at the end to free all resources. - //LibHeifInitializer initializer; + LibHeifInitializer initializer; int quality = 50; bool lossless = false; From 19e9d313133fe119d945d04ab5469fa3408e7ddc Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Wed, 31 Aug 2022 22:51:49 +0200 Subject: [PATCH 0107/3088] Create FUNDING.yml --- .github/FUNDING.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..f12d8c89e7 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: [farindk] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From be0fc732aeb05d00f86aa6f03db1c454236b11fa Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Wed, 31 Aug 2022 22:58:01 +0200 Subject: [PATCH 0108/3088] added links to software using libheif --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index abd5d8bf0f..51fca55903 100644 --- a/README.md +++ b/README.md @@ -221,11 +221,11 @@ to update the gdk-pixbuf loader database. ## Software using libheif -* GIMP -* Krita -* ImageMagick -* digiKam 7.0.0 -* libvips +* [GIMP](https://www.gimp.org/) +* [Krita](https://krita.org) +* [ImageMagick](https://imagemagick.org/) +* [digiKam 7.0.0](https://www.digikam.org/) +* [libvips](https://github.com/libvips/libvips) * [Kodi HEIF image decoder plugin](https://kodi.wiki/view/Add-on:HEIF_image_decoder) * [bimg](https://github.com/h2non/bimg) * [GDAL](https://gdal.org/drivers/raster/heif.html) From e3daf407c6ab60067f65c1c9e6b4f3f1973c0a6a Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 19:20:37 +0200 Subject: [PATCH 0109/3088] add darktable to list of applications using libheif --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51fca55903..a49d52353e 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,7 @@ to update the gdk-pixbuf loader database. * [GIMP](https://www.gimp.org/) * [Krita](https://krita.org) * [ImageMagick](https://imagemagick.org/) +* [darktable](https://www.darktable.org) * [digiKam 7.0.0](https://www.digikam.org/) * [libvips](https://github.com/libvips/libvips) * [Kodi HEIF image decoder plugin](https://kodi.wiki/view/Add-on:HEIF_image_decoder) From e7cdc471b2f0a185045ea9584d521c26c8017c1d Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 21:26:12 +0200 Subject: [PATCH 0110/3088] fix memory leak --- libheif/heif_decoder_aom.cc | 6 +++--- libheif/heif_decoder_dav1d.cc | 6 +++--- libheif/heif_decoder_libde265.cc | 6 +++--- libheif/heif_plugin.h | 3 ++- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libheif/heif_decoder_aom.cc b/libheif/heif_decoder_aom.cc index 1608a7a2f7..f8d39faf99 100644 --- a/libheif/heif_decoder_aom.cc +++ b/libheif/heif_decoder_aom.cc @@ -213,9 +213,9 @@ struct heif_error aom_decode_image(void* decoder_raw, struct heif_image** out_im // --- read nclx parameters from decoded AV1 bitstream heif_color_profile_nclx nclx; - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, img->cp)); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, img->tc)); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, img->mc)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, img->cp), {}); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, img->tc), {}); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, img->mc), {}); nclx.full_range_flag = (img->range == AOM_CR_FULL_RANGE); heif_image_set_nclx_color_profile(heif_img, &nclx); diff --git a/libheif/heif_decoder_dav1d.cc b/libheif/heif_decoder_dav1d.cc index ecf7382e1a..a02679ba72 100644 --- a/libheif/heif_decoder_dav1d.cc +++ b/libheif/heif_decoder_dav1d.cc @@ -235,9 +235,9 @@ struct heif_error dav1d_decode_image(void* decoder_raw, struct heif_image** out_ // --- read nclx parameters from decoded AV1 bitstream heif_color_profile_nclx nclx; - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, frame.seq_hdr->pri)); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, frame.seq_hdr->trc)); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, frame.seq_hdr->mtrx)); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, frame.seq_hdr->pri), {}); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, frame.seq_hdr->trc), {}); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, frame.seq_hdr->mtrx), {}); nclx.full_range_flag = (frame.seq_hdr->color_range != 0); heif_image_set_nclx_color_profile(heif_img, &nclx); diff --git a/libheif/heif_decoder_libde265.cc b/libheif/heif_decoder_libde265.cc index 2fcabd54b4..2e4c5d9f55 100644 --- a/libheif/heif_decoder_libde265.cc +++ b/libheif/heif_decoder_libde265.cc @@ -341,9 +341,9 @@ static struct heif_error libde265_v1_decode_image(void* decoder_raw, struct heif_color_profile_nclx* nclx = heif_nclx_color_profile_alloc(); #if LIBDE265_NUMERIC_VERSION >= 0x01000700 - HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_color_primaries(nclx, (uint16_t)de265_get_image_colour_primaries(image))); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_transfer_characteristics(nclx, (uint16_t)de265_get_image_transfer_characteristics(image))); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_matrix_coefficients(nclx, (uint16_t)de265_get_image_matrix_coefficients(image))); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_color_primaries(nclx, (uint16_t)de265_get_image_colour_primaries(image)), { heif_nclx_color_profile_free(nclx);}); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_transfer_characteristics(nclx, (uint16_t)de265_get_image_transfer_characteristics(image)), { heif_nclx_color_profile_free(nclx);}); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, *out_img, heif_nclx_color_profile_set_matrix_coefficients(nclx, (uint16_t)de265_get_image_matrix_coefficients(image)), { heif_nclx_color_profile_free(nclx);}); nclx->full_range_flag = (bool)de265_get_image_full_range_flag(image); #endif heif_image_set_nclx_color_profile(*out_img, nclx); diff --git a/libheif/heif_plugin.h b/libheif/heif_plugin.h index 46a06df19b..f7a4fde3b8 100644 --- a/libheif/heif_plugin.h +++ b/libheif/heif_plugin.h @@ -279,10 +279,11 @@ extern struct heif_error heif_error_ok; extern struct heif_error heif_error_unsupported_parameter; extern struct heif_error heif_error_invalid_parameter_value; -#define HEIF_WARN_OR_FAIL(strict, image, cmd) \ +#define HEIF_WARN_OR_FAIL(strict, image, cmd, cleanupBlock) \ { struct heif_error e = cmd; \ if (e.code != heif_error_Ok) { \ if (strict) { \ + cleanupBlock \ return e; \ } \ else { \ From 29490757acd5165ff6a3e0c2597f3b35d5d95743 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 21:31:10 +0200 Subject: [PATCH 0111/3088] fix resource leaks in fuzzers --- libheif/encoder_fuzzer.cc | 3 +-- libheif/file_fuzzer.cc | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libheif/encoder_fuzzer.cc b/libheif/encoder_fuzzer.cc index 059ece77c7..f516ac7011 100644 --- a/libheif/encoder_fuzzer.cc +++ b/libheif/encoder_fuzzer.cc @@ -185,12 +185,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) err = heif_context_encode_image(context.get(), image, encoder, nullptr, &img); heif_image_release(image); heif_encoder_release(encoder); + heif_image_handle_release(img); if (err.code != heif_error_Ok) { return 0; } - heif_image_handle_release(img); - MemoryWriter writer; struct heif_writer w; w.writer_api_version = 1; diff --git a/libheif/file_fuzzer.cc b/libheif/file_fuzzer.cc index 96a2e44b60..0990669643 100644 --- a/libheif/file_fuzzer.cc +++ b/libheif/file_fuzzer.cc @@ -30,7 +30,7 @@ static const enum heif_chroma kFuzzChroma = heif_chroma_420; static void TestDecodeImage(struct heif_context* ctx, const struct heif_image_handle* handle, size_t filesize) { - struct heif_image* image; + struct heif_image* image = nullptr; struct heif_error err; bool primary = heif_image_handle_is_primary_image(handle); @@ -61,6 +61,7 @@ static void TestDecodeImage(struct heif_context* ctx, err = heif_decode_image(handle, &image, kFuzzColorSpace, kFuzzChroma, nullptr); if (err.code != heif_error_Ok) { + heif_image_release(image); return; } @@ -81,7 +82,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { struct heif_context* ctx; struct heif_error err; - struct heif_image_handle* primary_handle; + struct heif_image_handle* primary_handle = nullptr; int images_count; heif_item_id* image_IDs = NULL; @@ -122,6 +123,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) struct heif_image_handle* image_handle; err = heif_context_get_image_handle(ctx, image_IDs[i], &image_handle); if (err.code != heif_error_Ok) { + heif_image_handle_release(image_handle); // Ignore, we are only interested in crashes here. continue; } @@ -142,6 +144,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) } quit: + heif_image_handle_release(primary_handle); heif_context_free(ctx); free(image_IDs); return 0; From 2183e288057733065be9db55deae323de66b5165 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 21:34:24 +0200 Subject: [PATCH 0112/3088] fix memory leak --- libheif/heif_decoder_aom.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libheif/heif_decoder_aom.cc b/libheif/heif_decoder_aom.cc index f8d39faf99..4105a48c2d 100644 --- a/libheif/heif_decoder_aom.cc +++ b/libheif/heif_decoder_aom.cc @@ -213,9 +213,10 @@ struct heif_error aom_decode_image(void* decoder_raw, struct heif_image** out_im // --- read nclx parameters from decoded AV1 bitstream heif_color_profile_nclx nclx; - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, img->cp), {}); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, img->tc), {}); - HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, img->mc), {}); + nclx.version = 1; + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_color_primaries(&nclx, img->cp), { heif_image_release(heif_img); }); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_transfer_characteristics(&nclx, img->tc), { heif_image_release(heif_img); }); + HEIF_WARN_OR_FAIL(decoder->strict_decoding, heif_img, heif_nclx_color_profile_set_matrix_coefficients(&nclx, img->mc), { heif_image_release(heif_img); }); nclx.full_range_flag = (img->range == AOM_CR_FULL_RANGE); heif_image_set_nclx_color_profile(heif_img, &nclx); From 09b769dc4d1c05ea1a574687e8d8103262731c51 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 21:41:51 +0200 Subject: [PATCH 0113/3088] fix null dereference --- libheif/box.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libheif/box.cc b/libheif/box.cc index b82610c78c..d3ee61f057 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -1825,12 +1825,12 @@ std::string Box_colr::dump(Indent& indent) const std::ostringstream sstr; sstr << Box::dump(indent); - sstr << indent << "colour_type: " << to_fourcc(get_color_profile_type()) << "\n"; - if (m_color_profile) { + sstr << indent << "colour_type: " << to_fourcc(get_color_profile_type()) << "\n"; sstr << m_color_profile->dump(indent); } else { + sstr << indent << "colour_type: ---\n"; sstr << "no color profile\n"; } From bbe01ef851b776ec2f587603afb3e5657f2f0f73 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 21:47:59 +0200 Subject: [PATCH 0114/3088] initialize pointer to null in fuzzer --- libheif/file_fuzzer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/file_fuzzer.cc b/libheif/file_fuzzer.cc index 0990669643..95d2a25d18 100644 --- a/libheif/file_fuzzer.cc +++ b/libheif/file_fuzzer.cc @@ -120,7 +120,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) } for (int i = 0; i < images_count; ++i) { - struct heif_image_handle* image_handle; + struct heif_image_handle* image_handle = nullptr; err = heif_context_get_image_handle(ctx, image_IDs[i], &image_handle); if (err.code != heif_error_Ok) { heif_image_handle_release(image_handle); From 3bd92f12e1da9e7e62755e5bd7768ae16b62cc72 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 22:06:44 +0200 Subject: [PATCH 0115/3088] fuzzer: set primary_handle to null after releasing --- libheif/file_fuzzer.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/libheif/file_fuzzer.cc b/libheif/file_fuzzer.cc index 95d2a25d18..d45e22b198 100644 --- a/libheif/file_fuzzer.cc +++ b/libheif/file_fuzzer.cc @@ -103,6 +103,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) assert(heif_image_handle_is_primary_image(primary_handle)); TestDecodeImage(ctx, primary_handle, size); heif_image_handle_release(primary_handle); + primary_handle = nullptr; } images_count = heif_context_get_number_of_top_level_images(ctx); From f3f71c8d67ca3265b76c782e48eb6fc68950a0a6 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 1 Sep 2022 22:15:44 +0200 Subject: [PATCH 0116/3088] increase version to v1.13.0 --- CMakeLists.txt | 2 +- configure.ac | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f522032c53..7d9682761d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.13) -project(libheif LANGUAGES C CXX VERSION 1.12.0.0) +project(libheif LANGUAGES C CXX VERSION 1.13.0.0) # https://cmake.org/cmake/help/v3.1/policy/CMP0054.html cmake_policy(SET CMP0054 NEW) diff --git a/configure.ac b/configure.ac index 2f539bde9a..44be93a570 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ AC_PREREQ([2.68]) -AC_INIT([libheif], [1.12.0], [opensource@struktur.de]) +AC_INIT([libheif], [1.13.0], [opensource@struktur.de]) AC_CONFIG_SRCDIR([libheif/box.cc]) AC_CONFIG_HEADERS([config.h]) # Note: do not forget to set the version in the CMakeLists.txt file accordingly PROJECT_VERSION_MAJOR=1 -PROJECT_VERSION_MINOR=12 +PROJECT_VERSION_MINOR=13 PROJECT_VERSION_PATCH=0 PROJECT_VERSION_TWEAK=0 AC_SUBST(PROJECT_VERSION_MAJOR) @@ -19,9 +19,9 @@ AC_SUBST(PROJECT_VERSION_TWEAK) # If any interfaces have been added since the last public release, then increment age. # If any interfaces have been removed or changed since the last public release, then set age to 0. -LIBHEIF_CURRENT=13 +LIBHEIF_CURRENT=14 LIBHEIF_REVISION=0 -LIBHEIF_AGE=12 +LIBHEIF_AGE=13 AC_SUBST(LIBHEIF_CURRENT) AC_SUBST(LIBHEIF_REVISION) AC_SUBST(LIBHEIF_AGE) From 5fb52b6134d5e034b51637a86c6e8a7418b35df1 Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Fri, 2 Sep 2022 12:17:03 +0200 Subject: [PATCH 0117/3088] add gnome/CMakeLists.txt to source package --- gnome/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gnome/Makefile.am b/gnome/Makefile.am index a9c066e5a0..2c9d52a375 100644 --- a/gnome/Makefile.am +++ b/gnome/Makefile.am @@ -5,6 +5,7 @@ mime_dir = $(datadir)/mime/packages mime__DATA = heif.xml avif.xml EXTRA_DIST = \ + CMakeLists.txt \ heif.thumbnailer \ heif.xml \ avif.xml From e7d41416c189fcc88e18bca17d6dbba173cd0c84 Mon Sep 17 00:00:00 2001 From: Heiko Becker Date: Fri, 2 Sep 2022 20:50:49 +0200 Subject: [PATCH 0118/3088] Update catch to the latest 2.x version ...which currently is 2.13.9. This allows building with glibc >= 2.34, which otherwise produces: "catch.hpp:10376:58: error: call to non-'constexpr' function 'long int sysconf(int)' 10376 | constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; | ^~~~~~~~~~~" Closes #539. --- tests/catch.hpp | 3427 +++++++++++++++++++++++++++++++---------------- 1 file changed, 2266 insertions(+), 1161 deletions(-) diff --git a/tests/catch.hpp b/tests/catch.hpp index 303f664ffc..d2a12427b2 100644 --- a/tests/catch.hpp +++ b/tests/catch.hpp @@ -1,9 +1,9 @@ /* - * Catch v2.9.1 - * Generated: 2019-06-17 11:59:24.363643 + * Catch v2.13.9 + * Generated: 2022-04-12 22:37:23.260201 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. + * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -14,8 +14,8 @@ #define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 9 -#define CATCH_VERSION_PATCH 1 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 9 #ifdef __clang__ # pragma clang system_header @@ -66,13 +66,16 @@ #if !defined(CATCH_CONFIG_IMPL_ONLY) // start catch_platform.h +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ -# include -# if TARGET_OS_OSX == 1 -# define CATCH_PLATFORM_MAC -# elif TARGET_OS_IPHONE == 1 -# define CATCH_PLATFORM_IPHONE -# endif +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX @@ -132,36 +135,51 @@ namespace Catch { #endif -#if defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + #endif -#ifdef __clang__ +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic pop" ) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) #endif // __clang__ @@ -186,6 +204,7 @@ namespace Catch { // Android somehow still does not support std::to_string #if defined(__ANDROID__) # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE #endif //////////////////////////////////////////////////////////////////////////////// @@ -219,11 +238,7 @@ namespace Catch { //////////////////////////////////////////////////////////////////////////////// // Visual C++ -#ifdef _MSC_VER - -# if _MSC_VER >= 1900 // Visual Studio 2015 or newer -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -# endif +#if defined(_MSC_VER) // Universal Windows platform does not support SEH // Or console colours (or console at all...) @@ -233,12 +248,20 @@ namespace Catch { # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +# if !defined(__clang__) // Handle Clang masquerading for msvc + // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) +# endif // __clang__ + #endif // _MSC_VER #if defined(_REENTRANT) || defined(_MSC_VER) @@ -276,40 +299,56 @@ namespace Catch { #endif //////////////////////////////////////////////////////////////////////////////// -// Check if string_view is available and usable -// The check is split apart to work around v140 (VS2015) preprocessor issue... -#if defined(__has_include) -#if __has_include() && defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW -#endif + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE #endif -//////////////////////////////////////////////////////////////////////////////// -// Check if optional is available and usable -#if defined(__has_include) -# if __has_include() && defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL -# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // __has_include +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif -//////////////////////////////////////////////////////////////////////////////// -// Check if variant is available and usable +// Various stdlib support checks that require __has_include #if defined(__has_include) -# if __has_include() && defined(CATCH_CPP17_OR_GREATER) -# if defined(__clang__) && (__clang_major__ < 8) - // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 - // fix should be in clang 8, workaround in libstdc++ 8.2 -# include -# if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) -# define CATCH_CONFIG_NO_CPP17_VARIANT -# else -# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT -# endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) -# else -# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT -# endif // defined(__clang__) && (__clang_major__ < 8) -# endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // __has_include + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) # define CATCH_CONFIG_COUNTER @@ -334,10 +373,6 @@ namespace Catch { # define CATCH_CONFIG_CPP17_OPTIONAL #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) -# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -#endif - #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) # define CATCH_CONFIG_CPP17_STRING_VIEW #endif @@ -346,6 +381,10 @@ namespace Catch { # define CATCH_CONFIG_CPP17_VARIANT #endif +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE #endif @@ -362,25 +401,53 @@ namespace Catch { # define CATCH_CONFIG_POLYFILL_ISNAN #endif -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) # define CATCH_CONFIG_USE_ASYNC #endif +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) @@ -445,7 +512,7 @@ namespace Catch { SourceLineInfo( SourceLineInfo&& ) noexcept = default; SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; - bool empty() const noexcept; + bool empty() const noexcept { return file[0] == '\0'; } bool operator == ( SourceLineInfo const& other ) const noexcept; bool operator < ( SourceLineInfo const& other ) const noexcept; @@ -486,9 +553,10 @@ namespace Catch { } // end namespace Catch #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION // end catch_tag_alias_autoregistrar.h // start catch_test_registry.h @@ -515,6 +583,7 @@ namespace Catch { virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); std::vector const& getAllTestCasesSorted( IConfig const& config ); @@ -527,53 +596,30 @@ namespace Catch { #include #include #include +#include namespace Catch { /// A non-owning string class (similar to the forthcoming std::string_view) /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. c_str() must return a null terminated - /// string, however, and so the StringRef will internally take ownership - /// (taking a copy), if necessary. In theory this ownership is not externally - /// visible - but it does mean (substring) StringRefs should not be shared between - /// threads. + /// it may not be null terminated. class StringRef { public: using size_type = std::size_t; + using const_iterator = const char*; private: - friend struct StringRefTestAccess; - - char const* m_start; - size_type m_size; - - char* m_data = nullptr; - - void takeOwnership(); - static constexpr char const* const s_empty = ""; - public: // construction/ assignment - StringRef() noexcept - : StringRef( s_empty, 0 ) - {} - - StringRef( StringRef const& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ) - {} + char const* m_start = s_empty; + size_type m_size = 0; - StringRef( StringRef&& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ), - m_data( other.m_data ) - { - other.m_data = nullptr; - } + public: // construction + constexpr StringRef() noexcept = default; StringRef( char const* rawChars ) noexcept; - StringRef( char const* rawChars, size_type size ) noexcept + constexpr StringRef( char const* rawChars, size_type size ) noexcept : m_start( rawChars ), m_size( size ) {} @@ -583,101 +629,64 @@ namespace Catch { m_size( stdString.size() ) {} - ~StringRef() noexcept { - delete[] m_data; - } - - auto operator = ( StringRef const &other ) noexcept -> StringRef& { - delete[] m_data; - m_data = nullptr; - m_start = other.m_start; - m_size = other.m_size; - return *this; + explicit operator std::string() const { + return std::string(m_start, m_size); } - operator std::string() const; - - void swap( StringRef& other ) noexcept; - public: // operators auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } - auto operator[] ( size_type index ) const noexcept -> char; + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } public: // named queries - auto empty() const noexcept -> bool { + constexpr auto empty() const noexcept -> bool { return m_size == 0; } - auto size() const noexcept -> size_type { + constexpr auto size() const noexcept -> size_type { return m_size; } - auto numberOfCharacters() const noexcept -> size_type; + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception auto c_str() const -> char const*; public: // substrings and searches - auto substr( size_type start, size_type size ) const noexcept -> StringRef; + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; - // Returns the current start pointer. - // Note that the pointer can change when if the StringRef is a substring - auto currentData() const noexcept -> char const*; + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; - private: // ownership queries - may not be consistent between calls - auto isOwned() const noexcept -> bool; - auto isSubstring() const noexcept -> bool; - }; + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } - auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string; - auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string; - auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string; + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { return StringRef( rawChars, size ); } - } // namespace Catch -inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { return Catch::StringRef( rawChars, size ); } // end catch_stringref.h -// start catch_type_traits.hpp - - -#include - -namespace Catch{ - -#ifdef CATCH_CPP17_OR_GREATER - template - inline constexpr auto is_unique = std::true_type{}; - - template - inline constexpr auto is_unique = std::bool_constant< - (!std::is_same_v && ...) && is_unique - >{}; -#else - -template -struct is_unique : std::true_type{}; - -template -struct is_unique : std::integral_constant -::value - && is_unique::value - && is_unique::value ->{}; - -#endif -} - -// end catch_type_traits.hpp // start catch_preprocessor.hpp @@ -762,7 +771,7 @@ struct is_unique : std::integral_constant #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) @@ -774,35 +783,49 @@ struct is_unique : std::integral_constant template struct TypeList {};\ template\ constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ \ - template class L1, typename...E1, template class L2, typename...E2> \ - constexpr auto append(L1, L2) noexcept -> L1 { return {}; }\ + template \ + struct append { using type = T; };\ template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ - constexpr auto append(L1, L2, Rest...) noexcept -> decltype(append(L1{}, Rest{}...)) { return {}; }\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ template< template class L1, typename...E1, typename...Rest>\ - constexpr auto append(L1, TypeList, Rest...) noexcept -> L1 { return {}; }\ + struct append, TypeList, Rest...> { using type = L1; };\ \ template< template class Container, template class List, typename...elems>\ - constexpr auto rewrap(List) noexcept -> TypeList> { return {}; }\ + struct rewrap, List> { using type = TypeList>; };\ template< template class Container, template class List, class...Elems, typename...Elements>\ - constexpr auto rewrap(List,Elements...) noexcept -> decltype(append(TypeList>{}, rewrap(Elements{}...))) { return {}; }\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ \ template