Version 15.5.0
New Features
◼Added: Some improvements to SVG support
◼Added: Improved support for monitor scaling
◼Added: When moving PDF objects, the associated clipping path is moved too
◼Added: Face helper methods using IEVision:
DetectFaces,
straighten a photo by the eyes,
crop to the main face and
obscure faces
◼Added: Find similar and near-duplicate images using IEVision perceptual hashing:
FindSimilar,
FindSimilar,
GetPerceptualHash and near-duplicate removal with
RemoveDuplicates
◼Added: PDFium updated to v8076
◼Added:
SetTextFont to change the size and color of PDF text objects
◼Added: dsoSubsetNewFonts save option for TPdfDocument.SaveToFile, SaveToStream and SaveToBytes to embed only the used glyphs of fonts added by
AddText (greatly reduces file size). Save options can now be combined, e.g. [dsoRemoveSecurity, dsoSubsetNewFonts]
◼Added: TPdfAttachment.Description property to get and set the description of PDF file attachments
◼Added: Metadata can be written when saving via PDFium
◼Added: PDF properties (Title, Author, Subject, Keywords, Creator and Producer) can be edited in
TIEMetaListView by adding iemPDF to
EditableTypes, and saved to a PDF file using
SaveMetaToFile
◼Added: Color and Style of PDF bookmarks are returned by TPdfDocument.BookmarksGetInfo
◼Added: WIA 2.0 support (Windows Vista and newer), including separate flatbed and feeder items. Set
WiaVersion to iewvAuto to use it when available (default is WIA 1.0). See also
ActiveWiaVersion
◼Added:
SetResolution sets the resolution of a WIA scan and scales the scan frame so that the same area is scanned
◼Added:
WiaVersion can now be changed after WIA has been used. The new version is used from the next refresh or connection (see
ActiveWiaVersion)
◼Added: Support for Windows on ARM
◼Added: Loading of 8 bit multichannel and 32 bit grayscale PSD/PSB files (multichannel images show the first channel as grayscale)
◼Added: Review of all language localization strings
◼Added:
SystemDialogCentering positions Windows system dialogs (AVI codec, WIA, DirectShow, color, font and print). Open, save and folder dialogs have their own DialogCentering property, which defaults to screen center
◼Added: Can specify a default value for IEAVISelectCodec()
◼Added: Many improvements to MMF and DirectShow support
◼Added: When saving a DICOM whose pixel values were adjusted during loading (see
DICOM_Range), Rescale Slope and Rescale Intercept tags are written so that pixel values map back to their original units (e.g. Hounsfield units), rather than being removed. Window Center and Window Width are also written in rescaled units
◼Added:
DICOM_PixelToValue returns the original value of a DICOM pixel (e.g. Hounsfield units), taking into account the adjustment of pixel values when loading
◼Added: Soft shadow color can be specified in Layer Properties dialog
◼Added: Modernize UI fonts in all dialogs
◼Added: Circular magnify layers have circular selection borders
Code Safety
◼Added: Recursion depth limit when parsing nested XML/JSON in
TIEDictionary
◼Added: Bounds checks when reading icon and cursor group resources in
TIEResourceExtractor
◼Added: Overflow and negative-size guards in
TIEList, TIEByteArray, IEAutoAlloc and IECheckedBufferSize
◼Added: Empty-array and empty-string guards in IECopyArrayOfByte, IECopyArrayOfInteger and TIEDictionary.DumpStructure
◼Added: Bounds checks in IEConvertAStringToGUID and clipboard Unicode paste
◼Added: Caps huge page ranges in
IEStrToIntArray
◼Added: Restores global format settings if IEFormat fails
◼Added: Loads MSIMG32.DLL and mscms.dll from the Windows System directory
◼Added: Safer creation of temporary files in TIETemporaryFileStream
◼Added: Command-injection guard when ImageMagick counts PDF pages
◼Added: Bounds checks when loading IPTC, ICC profiles, Wang/Imaging annotations and DICOM tag values
◼Added: Validate buffer in
Read and optional BufferSize for
LoadRawFromBufferOrStream
◼Added: Nil-scanline guards in TIEWorkBitmap and after realloc in TIEVirtualImageList
◼Added: Validate dimensions in
EncapsulateMemory
◼Added: Palette count clamp in TIEBitmap.CopyPaletteFromTBitmap
◼Added: Guard against invalid index in
ReleaseBitmap and failed load in
FillFromDirectory
◼Added: Source-rect clamp in
StretchRectTo
◼Added: Empty-input guard in IEASCII85EncodeBlock
◼Added: Overflow guards in
TIEList.InsertItem and .Delete for extremely large lists
◼Added: Clamp when colorCount exceeds the palette size in IEFindNearestColor
Bug Fixes
◼Fixed:
OnAddMetaData returned iemGeneral instead of iemPDF as the MetaType for PDF properties
◼Fixed: TPdfDocument save options were passed to PDFium as ordinal values, so dsoRemoveSecurity used a deprecated PDFium flag
◼Fixed: TWAIN duplex ADF acquire stopped after the first image when pendingXfers.Count is unknown
◼Fixed: TWAIN multi-page acquire may not terminate when the source reports a constant pendingXfers.Count (e.g. some Kyocera ADF drivers)
◼Fixed: Does not cope with 32bit Bitmap images that do not use A channel
◼Fixed:
TIEPolylineLayer elliptical arcs (iepaArcTo) draw incorrectly when freely rotated, or rotated by 90 or 270 degrees (wrong radii/angle; bulge may reverse)
◼Fixed: Windows scaling may affect text in IEN and SVG files when loading
◼Fixed: Arc radii (iepaArcTo) were not converted to the point base in
SetPoints,
SetPoint,
AddPoint and
GetPoints when using iepbRange or iepbClientArea
◼Fixed: When a locked layer was selected,
FindLayerAt returned -1 for any layer beneath it, even if the position was not over the locked layer. These layers could not be clicked, moved or show hints
◼Fixed: When
mlEditLayerPoints and mlRotateLayers were used together, point layers (
TIELineLayer,
TIEPolylineLayer and
TIEAngleLayer) could be rotated by clicking where the rotation grip would be, even though the grip was not shown
◼Fixed: When multiple layers were selected and
mlEditLayerPoints was used, grips could be drawn for point layers or hidden for other layers depending on which layer was current
◼Fixed: Images and layers without an alpha channel had their opacity applied twice when drawn (e.g. a
Opacity of 0.5 drew at 25%)
◼Fixed: Text layers saved by
SaveToFileSVG used the wrong font size when Windows scaling is not 100%
◼Fixed:
SaveToFileSVG could create an invalid SVG file ("Encoding error") when a layer name, hint, text or font name contained accented or other non-ASCII characters
◼Fixed: Layer names and URLs were not imported from SVG files by
LayersImport for shape, line, polyline and text layers, and assigning
AsSVG to an image layer cleared its name and URL
◼Changed: When importing SVG files as layers,
Name is now read from the id attribute and
Hint from the title element (matching how layers are saved by
SaveToFileSVG). Previously the title was assigned to Name
◼Fixed: Loading an IEN file in layer editing mode set
ModifiedDate of image layers to the current time and
Modified to True, so a file that was only opened and saved again was changed
◼Fixed: The
layer properties control showed and applied the wrong font size for text layers when Windows scaling is not 100%
◼Fixed: Editing a
formatted text layer could start at the wrong font size when Windows scaling is not 100%
◼Fixed:
Formatted (rich text) layers were drawn larger when Windows scaling is not 100% (e.g. 1.5x at 150%), so they did not match plain text layers of the same size and the content of IEN files changed with the system scaling
◼Fixed: Text layers created by
AssignAsLayers could have the wrong font size on monitors with non-100% scaling
◼Fixed: Saving a 32bit image that does not use the A channel as WebP produced a transparent image
◼Fixed: Saving a 32bit (ie32RGB) image as PSD swapped the red and blue channels, and wrote unused A bytes as transparency
◼Fixed: Saving image layers to PDF could output a corrupted image when the layer was not 24bit or black and white (native engine), or a transparent image for 32bit layers that do not use the A channel (PDFium)
◼Fixed: ICO and CUR files with fewer palette entries than the bit depth allows could fail to load or load with the wrong colors
◼Fixed: Image size meta-data not set when loading WebP in TImageEnMIO
◼Fixed:
Assign, AssignImage and AssignRect could destroy the image on self-assignment
◼Fixed:
Fill used the wrong or uninitialized color when deciding if CMYK, CIELab, 48-bit RGB or RGBA fills were solid white
◼Fixed: TIEBitmap.ConvertToPixelFormat left pixel format out of sync for unsupported ieTBitmap conversions
◼Fixed: Resizing an empty
TIEBitmap stored as a TBitmap (
Location = ieTBitmap), e.g. after
FreeImage, created an invalid image. For example,
LayersDrawTo drew nothing into a bitmap previously used by
DrawTo
◼Fixed: TIEBitmap.GetPalette returned an uninitialized color for an out-of-range index
◼Fixed: ASCII85 decode of a partial final group could corrupt the last bytes
◼Fixed: TIERandomGenerator.NextINT64 discarded the high 32 bits
◼Fixed: TIEIntegerMap hash never used the last bucket
◼Fixed: IEGetNewFilename could generate a garbled filename for a purely-numeric input
◼Fixed:
GetInteger could raise an exception for a non-numeric string value
◼Fixed:
GetString could raise an exception for an array-valued key
◼Fixed:
GetBoolean could raise an exception for an array-valued key
◼Fixed:
GetDouble could raise an exception for an array-valued key
◼Fixed: IEFlattenCubicBezier could recurse indefinitely for a NaN or Infinity control point
◼Fixed: IESimplifyPolygon could recurse to a stack-overflow depth for a large, unbalanced input
◼Fixed: IECheckedBufferSize silently returned a wrapped/negative size instead of raising on a 64-bit build
◼Fixed: IEFindInStream could miss a match ending exactly at the stream's last byte
◼Fixed:
ImportMetafile could compute an incorrect (far too large) destination size for a metafile with an extreme declared width/height, due to an internal 32-bit overflow
◼Fixed:
LoadSelectionFromStream could allocate/read using two untrusted stream counts (point count and per-polygon value count) that were not validated against the stream's actual remaining size
◼Fixed: TImageEnView.LayersLoadFromStream>trusted an untrusted stream's declared layer count with no validation, allowing a small malicious file to drive an effectively unbounded per-layer allocation loop
◼Fixed:
PasteFromClipboard and
PointPasteFromClip could read past the end of a truncated or malicious clipboard buffer when pasting the ImageEn-internal clipboard format
◼Fixed:
Convolve could bypass its own Kernel/KernelWidth/KernelHeight size validation via 32-bit integer overflow, driving a heap buffer overflow with mismatched kernel dimensions
◼Fixed:
SelectMagicWand,
LayersCreateFromEdge and other IEMakeMagicWandPoints callers could overflow a 32-bit row-buffer size computation and corrupt the heap when the flood-filled region was large
◼Fixed: Internal chain-code buffer used by selection/mask vectorization (IEVectorize) could overflow its own capacity-doubling calculation for an extremely long traced contour
◼Fixed:
RoundImage could overflow a 32-bit buffer-size computation and corrupt the heap for a large RoundWidth/RoundHeight combination
◼Fixed:
SelectEllipse,
SelectShape and other vectorized-selection-building APIs could overflow the shared point-array capacity-doubling calculation (TIEVectorizedSelection.CheckCapacity) and corrupt the heap for a very large selection
◼Fixed: Loading a polyline layer from a saved layers/project file trusted the file's claimed point count with no check against the file's actual size, and a legacy-format file could additionally overflow the point buffer's own 32-bit size computation, causing an out-of-bounds heap read
◼Fixed:
SmoothJaggedEdges could overflow two internal 32-bit buffer-size computations and corrupt the heap for a polyline with a very large number of points, and could leak memory if the second allocation failed
◼Fixed: Loading a TIFF file's StripOffsets/StripByteCounts/TileOffsets/TileByteCounts tags could overflow a 32-bit buffer-size computation and corrupt the heap for a tag claiming a very large (but otherwise valid) count
◼Fixed:
InjectTIFFEXIF and other TIFF re-saving operations could overflow a 32-bit buffer-size computation and corrupt the heap when re-reading or re-writing a TIFF file with a StripOffsets or TileOffsets tag claiming a very large count
◼Fixed: Adding many points to a polyline/vector layer, or enabling complex-path point formatting on a large one, could overflow a 32-bit buffer-size computation and corrupt the heap
◼Fixed: Setting
LayersSelectedList with a negative index could corrupt the heap
◼Fixed: Loading or extracting from a ZIP/7z archive with an out-of-range file index (e.g. from a stale
ImageIndex left over from a previously-loaded, larger archive) is now rejected instead of being passed unchecked to the underlying 7z library
◼Fixed: HEIF/AVIF image-index lookup (
LoadFromFileHeif) could overflow a 32-bit buffer-size computation for an extreme top-level image count
◼Fixed: Loading an SVG polygon/polyline with an extremely long <points> attribute could allocate unbounded memory before the existing point-count limit was enforced
◼Fixed: Loading a PSD/PSB layer with an implausibly large declared size could fail to allocate and then write through an invalid bitmap pointer instead of aborting the layer
◼Fixed: Loading a PSD/PSB file with RLE-compressed channel data could read past the end of an internal decompression buffer for a row whose declared compressed size didn't match its actual RLE-encoded content
◼Fixed: Loading a DICOM file with a mismatched Palette Color LUT Descriptor/Segmented Palette Color LUT Data could read and write past the end of an internal lookup table buffer
◼Fixed: Loading a DICOM file with a self-referencing "Indirect" segmented palette segment could recurse indefinitely and crash
◼Fixed: Loading a DICOM image with an implausibly large declared size could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed: Loading a DICOM image whose Rescale Slope gives a fractional pixel value range (e.g. a near-binary image saved with Rescale tags) could produce a blank image due to floating point error. Also, the maximum pixel value could be reduced by one each time such a DICOM was saved and reloaded
◼Fixed: Saving a JPEG with an assigned ICC profile larger than about 7.8MB could write a corrupted, unrecoverable ICC profile into the file's APP2 markers
◼Fixed: Loading a PNG file with an implausibly large declared size, or an uncommon low bit-depth grayscale combination, could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed: Loading a TIFF file declaring more than 10 samples per pixel could overrun several internal fixed-size arrays
◼Fixed: Loading an LZW-compressed TIFF file with a truncated or undersized compressed strip could read past the end of an internal buffer
◼Fixed: Loading a Deflate/ZIP-compressed TIFF file whose strip decompresses to fewer bytes than its declared size could read past the end of an internal buffer
◼Fixed: Deleting, inserting, or extracting a page from a multi-page TIFF file with a malformed or mismatched tag could read or write past the end of an internal buffer
◼Fixed: Loading a BI_RLE4-compressed BMP file whose compressed data ended mid-opcode could read past the end of an internal buffer
◼Fixed: Loading a PBM/PGM/PPM file with an implausibly large declared size could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed: Loading a BMP, ICO, or CUR file whose palette was smaller than its bit depth implied could read past the end of the palette
◼Fixed: Exporting a very large black-and-white image to PostScript could write past the end of an internal buffer
◼Fixed: Loading a GIF file with an implausibly large declared frame size could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed: A crafted GIF file's LZW-compressed image data could cause decoding to write past the end of an internal buffer
◼Fixed: Checking or creating a looping animated GIF could read a few bytes past the end of an internal constant
◼Fixed: A malicious VNC server could write past the end of an internal buffer via a crafted framebuffer update
◼Fixed: A malicious VNC server could write past the end of an internal buffer via a crafted cursor shape update
◼Fixed: A malicious VNC server could force an excessive memory allocation via an oversized clipboard, desktop name, or error message
◼Fixed: The VNC client's reported screen size could disagree with its actual framebuffer size after an oversized screen was declared by the server
◼Fixed: Downloading a file via
IEGetFromURL could read past the end of an internal buffer, or hang indefinitely, if the connection failed partway through a transfer
◼Fixed: Retrieving a dropped URL (e.g. an image dragged from a web browser) could read past the end of the dropped data if it was not correctly NUL-terminated
◼Fixed:
CutFilesToClipboard and
CopyFilesToClipboard could place an incorrectly-terminated file list on the clipboard for certain input strings
◼Fixed: Pasting files from the clipboard could pass an invalid handle to the Windows Shell API in rare cases where another application accessed the clipboard at the same time
◼Fixed: A folder-change notification could read past the end of an internal buffer if the underlying Windows notification data was truncated or malformed
◼Fixed: Loading a file via a legacy external-DLL format plug-in (
IEAddExtIOPlugin) with an implausibly large declared size could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed:
IEGenerateSampleImage could write past the end of an internal buffer for an implausibly large declared size, due to a failed-allocation check that could never actually detect the failure
◼Fixed: Loading a JPEG2000 (JP2/J2K) file with an implausibly large declared size, using the external OpenJPEG engine, could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed: Loading a JPEG2000 (JP2/J2K) file whose header declared an unsupported color space, using the native (32-bit) JPEG2000 decoder, could corrupt memory via a double-free
◼Fixed: Loading a JPEG2000 (JP2/J2K) file with an implausibly large declared size, using the native (32-bit) JPEG2000 decoder, could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed: The resolution (
DpiX and
DpiY) of JPEG2000 (JP2) files was not read when loading (the default DPI was always returned), using either the external OpenJPEG engine or the native JPEG2000 decoder. The capture resolution (resc box) is now used, or the default display resolution (resd box) if not available
◼Fixed: Loading a camera RAW file whose decoded image had an implausibly large size could fail to allocate and then write through an invalid bitmap pointer instead of aborting
◼Fixed: A malformed camera RAW (CRW) file's maker-note tag could leave part of an internal buffer uninitialized, exposing stray memory contents via
EXIF_MakerNote
◼Fixed: A malformed camera RAW (CRW) file could cause excessive recursion while extracting its embedded JPEG preview
◼Fixed: TWAIN memory-mode image transfer trusted the scanner/camera driver's own reported transfer-size fields, risking an out-of-bounds read from the transfer buffer for a misbehaving driver
◼Fixed: TWAIN capability negotiation (e.g. reading
XResolution, YResolution, PixelType, BitDepth) trusted the driver-reported item count of an enumerated/array capability with no check against the capability data's real size
◼Fixed: Converting a device-independent bitmap (DIB) handle to a bitmap (TWAIN native transfer, clipboard, capture drivers) trusted the DIB header's size fields, so a header describing more data than the memory block held could read past the end of the block. A failed bitmap allocation could also write through an invalid pointer
◼Fixed: WIA scanner/camera support trusted driver-reported property-list counts and thumbnail dimensions with no check against the real size of the returned data, risking an out-of-bounds read from a misbehaving WIA driver
◼Fixed: Memory leak of the WIA data callback object after acquiring from a WIA scanner or camera
◼Fixed:
FillTreeView leaked a TTreeNode each time it was called
◼Fixed: Copying a virtual (memory-mapped) image into a
TIEBitmap could write through an invalid bitmap pointer if the bitmap allocation failed
◼Fixed:
CopyTag,
SaveTagToFile,
DeleteTag and TIFF re-saving used unchecked 32-bit arithmetic for a tag's data size, which for a crafted TIFF with a huge strip/tile offset count could overflow and corrupt the heap
◼Fixed:
WriteStream and
WriteFile leaked memory each time a page with multiple strips or tiles was written (this also affected re-saving TIFF files with modified EXIF)
◼Fixed: Loading an IEV (vectorial objects) file with a corrupt or hostile object count, string length, point count, bitmap index or bitmap count could allocate gigabytes, read or write out of range, or raise an access violation;
LoadFromFileIEV now rejects such files, and no longer leaves shared-bitmaps mode on after a failed load
◼Fixed: Media Foundation video capture and media file decoding computed frame buffer sizes and strides from device or file reported values using wrapping 32-bit arithmetic (and ignored the stride for NV12), which could make the converter read past the end of the frame buffer; a huge sample timestamp could make the callback thread sleep for days, and a media type with no entries looped billions of times. Values are now validated and unreadable media-type values are no longer used uninitialised
◼Fixed: Media Foundation capture and playback (especially with audio rendering) could randomly raise an access violation or close the application without a message, because callbacks on Media Foundation threads used the memory manager without thread locking
◼Fixed: Media Foundation playback of a media file stopped when the first of its streams ended (e.g. a soundtrack shorter than the video), instead of when all selected streams had ended
◼Fixed: Media Foundation frames in YUY2 or I420 format with padded rows were displayed skewed, and frames whose media type did not report a stride were dropped
◼Fixed: The Media Foundation video processor (
VideoProcessor) was given an invalid rotation of 360 degrees on a normally oriented display, which could make it stop processing (including mirroring) for the rest of the capture
◼Fixed: DirectShow video capture and file decoding trusted driver reported stream capability counts and sizes, media-type format blocks and sample sizes; a hostile or buggy driver could make capability enumeration loop for billions of iterations, cause an over-read of the format block, or leak the media type. A video file that does not advance its position could also make frame stepping loop for ever
◼Fixed: When capturing to a file (
FileOutput) with
RenderVideo enabled, cameras with more than one capture stream (e.g. a color and an IR sensor) could show a different stream in the preview (e.g. a black or grayscale image) to the one being written to the file
◼Fixed: Passing an unrecognized format to
SetVideoInput or
SetCurrentVideoFormat silently used the CLPL format. An exception is now raised, and any four character code (e.g. 'NV12', matched without regard to case) is accepted
◼Fixed: Video formats that are not in ImageEn's internal list (e.g. NV12) returned an empty
VideoFormats.Format. The four character code is now returned
◼Changed: When no format is passed to
SetVideoInput, the format the device is currently set to is used if it supports that size (otherwise the format reporting the highest bitrate, as before)
◼Fixed:
SetCurrentVideoFormat did not report a format the device refused (an exception is now raised), and edited the current media type instead of using the device's own media type for the requested format and size (so a new format kept the old compression and bit depth)
◼Fixed: Connecting an audio input (
SetAudioInput) with
RenderAudio enabled and no
FileOutput did not play the audio input
◼Fixed:
FileOutput did not accept .wmv files (written by the ASF writer like .asf)
◼Fixed:
GetAverageTimePerFrame could start a capture graph (recording to
FileOutput) and left the graph paused at a later position when the frame time had to be measured (a stopped or paused graph is now restored). Its documentation now gives the correct unit (100-nanosecond units, not milliseconds)
◼Fixed:
Rate and
State could return undefined values when the graph did not provide them, and
Connect raised an access violation instead of an exception if DirectShow is not available
◼Fixed:
IEMediaFoundationTimeToSec returned values 100 times too small and
IESecToMediaFoundationTime values 100 times too large (they used nanoseconds instead of 100 nanosecond units), so e.g. seeking with
SetPosition went past the end of the media
◼Fixed: Media Foundation RGB frames could be decoded upside down (e.g. WMV files read with
TIEMediaFoundationSourceReader), as the row order was taken from the media type instead of the frame buffer
◼Fixed:
ConvertTimeFormat raised an access violation (32bit) or returned a wrong value (64bit)
◼Fixed:
Connect succeeded with a graph that produced no frames if the
FileInput file did not exist, could not be read or had no video that could be decoded (an exception is now raised)
◼Fixed:
OpenMediaFile reported the wrong frame count (e.g. 367 instead of 40) for media files that do not specify a frame rate (e.g. WMV), so
LoadFromMediaFile returned the wrong frames.
MEDIAFILE_FrameDelayTime is also now taken from the frame time (it was wrong when the audio track is longer than the video).
GetAverageTimePerFrame now measures the frame time from the decoded sample time stamps
◼Fixed: When
OpenMediaFile failed to open a file,
IsOpenMediaFile still returned True. It now returns 0 (instead of raising an exception) and closes the file
◼Fixed: PDF rendering and editing (TPdfDocument, TPdfObjectList and the PDF outline reader) ignored negative array indexes and counts, truncated stream sizes above 2 GB, accepted a short ReadFile as success, ignored stream read errors when loading saved objects, trusted object point counts, and could loop for ever on an outline whose /Next entries form a cycle
◼Fixed:
TIEPDFBuilder raised an exception when a page was inserted beyond the page list, associated the wrong content stream with a page inserted before existing pages, wrote a freed object when saved a second time, wrote duplicate /Parent and /Pages entries when saved repeatedly, and raised an access violation when adding content (e.g.
AddImage) before adding any page (it now raises EIEException)
◼Fixed: Portable device (WPD) support trusted device reported values: object enumeration with a failed or empty result used uninitialised object ids, folder trees and enumeration counts were unbounded (a device with cyclic folders could recurse for ever), names were not length checked, file names containing path separators or reserved names were used as the local file name, and a truncated or failed read or write when copying a file to or from the device was treated as success (so the MoveFile parameter of
CopyFileFromDevice and
CopyFileToDevice could delete the source after a partial copy)
◼Fixed: CSV export of image meta-data (
TIEMetaListView) did not escape double quotes in values, which let image-supplied text inject extra columns, and did not neutralise values that begin with a formula character (=, @, or +/- followed by text), which allowed CSV/formula injection when the file was opened in a spreadsheet; parsing MOV/MP4 atoms with a huge 64-bit size could also overflow and seek to a wrong position
◼Fixed: Shell thumbnail and shortcut helpers converted STRRET strings returned by shell folders without checking the offset or length against the item id list or assuming a terminating NUL, used output values uninitialised when a shell call succeeded with S_FALSE, and ignored a failed bitmap allocation
◼Fixed: The Google API helpers (
TIEGoogleVision and the map and geocoding requests) hard-cast every item of the parsed JSON response to a dictionary, so a response with an unexpected structure caused an access violation, and map coordinates were formatted using the local decimal separator
◼Fixed:
TIEEquirectangularRenderer and
TIESlippyMap used GPano XMP values from the image, tile images from tile servers and the provider URL mirror list without validation, which could cause division by zero, out-of-range reads or writes of tile data, or an invalid clipped rectangle; invalid values are now rejected or normalised
◼Fixed:
TIEFolderTree (builds without shell thumbnail support) converted shell item names without checking the offset or length against the item id list, used an uninitialised PIDL in an internal helper, and used the uninitialised description id of a folder whose lookup failed to decide whether to hide it
◼Fixed:
TIEFolderTree folder nodes could be used by their change-monitor thread after the node had been freed,
PathToNode and TIEFolderTree.GetSpecialNodeByPath raised an access violation when the tree has no root node, a WM_DEVICECHANGE message with a nil header raised an access violation, and a zip file containing folder paths with thousands of levels could exhaust the stack when expanded in the tree
◼Fixed:
TIEDBBitmap and
TIEDBMultiBitmap built the path of a linked image file from the file name stored in the database without removing parent folder references, so a name such as "..\..\Windows\win.ini" in the database could make the component load, or later save over, a file outside
ImagePath. Such names are now reduced to their bare file name
◼Fixed: The colour quantizer used when reducing colours (TIEQuantizer,
CalcImagePalette, saving paletted images) did not check that the palette array was large enough, so a palette array shorter than the requested number of colours was overrun (it now raises EIEException); the median cut algorithm overran its box list when more than 256 colours were requested (Kohonen is used instead), reducing a gray image to one colour divided by zero, a
ColorReductionQuality above 100 could cause a division by zero, and a very large colour count could cause an out of range access in the Kohonen algorithm
◼Fixed: The LoadFromRegistry and LoadFromIniFile helper methods (iexRegistryFunctions) stored out of range numbers directly in enumerated properties such as
MsgLanguage,
DialogMeasureUnit,
TImageEnView.BackgroundStyle,
ZoomFilter,
ThumbnailResampleFilter and the acquire orientation, pixel type and rotation, which could cause out of range accesses later; an invalid value now gives the default
◼Fixed:
TOpenImageEnDialog and
TSaveImageEnDialog used
OpenDialogMaxMultiSelFiles unchecked to size the file name buffer, so a value of zero, a negative value or an extremely large value caused an empty, huge or overflowing buffer; the value is now limited to 1..100,000
◼Fixed: Loading a 4 or 8 bit cursor (CUR) with only 2 palette entries could corrupt memory
◼Fixed: Loading a 4 bit ICO or CUR with an odd width could write past the end of the image. 4 bit ICO files loaded with NativePixelFormat and IgnoreAlpha had every second pixel wrong
◼Fixed:
IEWriteICOImages raised an access violation if an item was not a
TImageEnView, and changed the Channel of the views
◼Fixed: DICOM Segmented Palette Color LUTs using "Indirect" segments decoded those entries as black
◼Fixed: Loading a PALETTE COLOR DICOM with a missing or short green/blue LUT could raise an access violation
◼Fixed: Loading a 16 or 32 bit PSD with an uncompressed layer mask could corrupt memory. 16 bit layer masks were decoded with the wrong values
◼Fixed:
DeleteTIFFImGroup did not delete all pages if the indexes were not in ascending order
◼Fixed:
EnumTIFFIm,
EnumICOIm,
DeleteTIFFIm and
DeleteTIFFImGroup raised an exception for a missing file instead of returning 0
◼Fixed:
DeleteGIFIm overwrote the file with an empty or partial GIF if it was not a valid GIF or was truncated, and raised an exception for a missing file instead of returning 0.
EnumGIFIm leaked memory for a missing file
◼Fixed:
MergeAlphaRectTo made the whole destination opaque (rather than just the rect) when the source has no alpha channel
◼Fixed:
BitAlignment had no effect when
Location is ieFile
◼Fixed:
EncapsulateFragmentedMemory accepted fragments with fewer rows than the image height
◼Fixed: TImageEnMView.CopySelection raised an access violation for a nil source
◼Fixed:
ExtractFromFileZIP and
ExtractFromStreamZIP did not check the file indexes against the archive
◼Fixed: Copying through an 8 bit (graduated) selection mask, e.g.
CopyWithMask2, copied fully selected pixels at 255/256 of their value (e.g. 255 became 254)
◼Fixed:
DetectAndDeskew raised an OpenCV exception instead of returning False when no matching points were found (e.g. a blank image)
◼Fixed: Documentation referred to TIEColorPalette.TransparentStyle instead of
TransparentCellStyle
◼Fixed: Documentation review: code examples that did not compile, declarations and enum values that did not match the source, and many spelling and grammar errors
◼Fixed: Issues when downscaling images using rfFastLinear if they use the alpha channel
◼Fixed:
IEVisionMatrixToMatrix returned incorrect values for matrices from
findHomography (64 bit values were read as 32 bit, and the matrix was read transposed). It now also accepts 2x3 affine matrices, e.g. from
getAffineTransform
◼Fixed: Assigning
LayersSelectedList reported layers that became selected as ielDeselected and layers that became deselected as ielSelected (
OnLayerNotify)
◼Fixed:
SelectMagicWand and other IEMakeMagicWandPoints callers could still overflow a 32-bit size computation and corrupt the heap for a flood-filled region about a billion pixels wide (e.g. a very wide black and white image)
◼Fixed:
SelectMagicWand and other IEMakeMagicWandPoints callers leaked memory if the flood fill raised an exception (e.g. for an extremely wide image)
◼Fixed: Pasting text from the clipboard (e.g. into a text layer editor) used each character code as a memory address, which could raise an access violation or paste the wrong text
◼Fixed: A folder-change notification with an extremely large file name length could pass the size check, due to a 32-bit overflow
◼Fixed: TWAIN memory-mode transfers only checked the driver-reported number of bytes written against the real transfer buffer when the image size was unknown in advance, so a misbehaving driver could cause an out-of-bounds read during a normal scan
◼Fixed: When Windows scaling is not 100%, choosing a font for a text layer (ietaPromptForFont) and closing the editor of a
formatted (rich text) layer could change the layer's font size (e.g. 12pt became 18pt at 150%)
◼Fixed: When scanning from a WIA 2.0 document feeder, the last page could be lost if the driver reported the feeder as empty without completing the page stream
◼Fixed: Increasing
XResolution or
YResolution of a WIA scanner could scan only part of the page, because the scan frame (which WIA specifies in pixels) was not adjusted for the new resolution
◼Fixed:
XScaling and
YScaling had no effect for WIA devices
◼Fixed: Writing a WIA property with a value of a different type than the property (e.g. a floating point value, a small integer constant or a string) using
SetItemPropertyVariant or
SetDevicePropertyVariant failed without an error
◼Fixed:
GetItemPropertyAttrib returned True with undefined attributes for a property that the device does not support, and leaked memory
◼Fixed:
SetValueRaw with a negative or very large data count could corrupt memory, due to an unchecked 32-bit size computation
◼Fixed: Locating a folder path on a portable device (WPD) could recurse without limit (stack overflow) if the device reported nested or cyclic folders with empty names
◼Fixed: TPdfDocument.LoadFromBytes and TPdfAttachment.SetContent raised an exception for an empty byte array
◼Fixed: Loading a 4 bit cursor (CUR) whose pixels used palette entries beyond the palette could leave some pixels with undefined colors; a failed allocation is now reported instead of continuing
◼Fixed: Canon CRW maker-note values (
EXIF_MakerNote) were read with twice their real length, including unrelated data that followed them in the file
◼Fixed: Saving a 32bit image that does not use the A channel with the WIC engine changed the source image (its A channel was set to fully opaque)
◼Fixed:
ScreenSize could disagree with the framebuffer after the VNC server changed the screen size while
Suspended was True
◼Fixed: Loading a PSD/PSB layer whose mask data includes mask parameters or a real user mask (or has a corrupt size) read the blending ranges, layer name and adjustment data from the wrong position
◼Fixed: Loading a 16 bit multichannel PSD used the second ink channel as the alpha channel
◼Fixed: JPEG files with malformed meta-data (e.g. a mistyped tag in the EXIF thumbnail) failed to load with the WIC engine or when
WicFastLoading is enabled
◼Fixed: SVG files with a large path (more than about 16,000 points) loaded as an empty image without any error, and large paths could crash with a stack overflow when assigned to
SetPoints or drawn with
DrawLinesPath. Point arrays are no longer copied onto the stack
◼Fixed: A
complex path (curves or arcs) containing a break (IE_PointArray_Break or IE_PointArray_ClosingBreak) included the break in its size, so a
TIEPolylineLayer could become enormous (and fail to draw) or have its points squashed into a corner
◼Fixed: Images returned by
getImage for a
TIEVisionTempFileImageList were freed when the list was destroyed, causing an access violation when they were released, and were changed by the next getImage call
◼Fixed:
Negative with specific channels inverted the wrong channel of ie32RGB images (Red and Blue were swapped)
◼Fixed: Rescale Slope and Rescale Intercept tags specified in
DICOM_Tags were removed when saving a DICOM image created in code (e.g. volume data)
◼Fixed: PNG text chunks (
PNG_Chunks, e.g. the "prompt" and "workflow" fields of AI generated images) and XMP were not loaded when using the WIC engine (e.g. 64bit apps without the IELib DLL) or
WicFastLoading
◼Fixed: EXIF, XMP, ICC and text meta-data were not loaded from a PNG that was not at the start of the stream (e.g.
LoadFromStream with a stream position other than 0)
◼Fixed: Rotated text in a
TIETextLayer with
TextOverflow = ieoShrink was not reduced enough to fit the layer (and at some angles not reduced at all), so it was cut off at the edges. ieoTruncate and ieoHide now also check the rotated text against the layer. This includes layers with
BorderRotate set. This also affects
AdvancedDrawText
◼Fixed: Rotated text that fitted its area tightly could be drawn off-center and cut off by
DrawText (with a bounding rect), e.g. a
TIETextLayer at 90 degrees with
TextOverflow = ieoShrink
◼Fixed: When dragging images from ImageEn controls, the thumbnail may be inverted
◼Fixed: Loading a DICOM file using an unsupported compression (e.g. JPEG-LS) displayed noise instead of failing
◼Fixed: With
AutoCurving or
AutoCurving enabled, shapes containing breaks (e.g. iesLink) and polylines with a section of fewer than three points raised an "Invalid point count" exception when drawn. Also, closed sections of such shapes and polylines are now curved as closed paths (previously a sharp corner remained at their start point)
Changes to Method Parameters
◼Added: Optional BufferSize parameter for
LoadRawFromBufferOrStream
◼Added: Optional Prepare parameter for
OCR to improve results with photos and poor scans by preprocessing the image with
prepareForOCR before recognition
Changes to Classes
◼None
Demo Changes
◼Added: "Prepare for OCR" option to the IEVision OCR demo (Demos\IEVision\OCR\OCR.dpr)
◼Added: New OCR preprocessing and other methods in the Every Method demo (Demos\ImageEditing\EveryMethod\EveryMethod.dpr)
◼Added: New IEVision demo to generate and detect QR codes (Demos\IEVision\QRCode\QRCode.dpr)
◼Added: New IEVision demo to generate and detect Aruco markers and Charuco chessboard corners (Demos\IEVision\Aruco\Aruco.dpr)
◼Added: Neural network (YuNet) face detection, with facial landmarks, to the IEVision Get Faces demo (Demos\IEVision\GetFaces\GetFaces.dpr)
◼Added: Convex hull, Delaunay triangulation, affine warp and polygon fill methods to the Every Method demo (Demos\ImageEditing\EveryMethod\EveryMethod.dpr)
◼Added: Choice of keypoint detector (ORB, SIFT, AKAZE, KAZE or BRISK) to the IEVision Image Alignment demo, which now defaults to SIFT and shows the match count and time (Demos\IEVision\ImageAlignment\ImageAlignment.dpr)
◼Added: Line removal, perceptual image hashing and feature detector methods to the Every Method demo (Demos\ImageEditing\EveryMethod\EveryMethod.dpr)
◼Added: Font size editing of text objects using
SetTextFont to the PDF Page Objects demo (Demos\PDF\PDFPageObjects\PDFPageObjects.dpr)
◼Added: WIA 2.0 option (
WiaVersion) to the WIA Scanner demo (Demos\ImageAcquisition\WIAScanner\WIAScanner.dpr) and the All Acquire demo (Demos\ImageAcquisition\AllAcquire\AllAcquire.dpr)
◼Changed: The WIA Scanner demo shows the WIA version in use, disables settings the device does not support, only writes the values that have been changed (including the orientation, which was not written) and reports the settings rejected by the device (Demos\ImageAcquisition\WIAScanner\WIAScanner.dpr)
◼Added: PDF Viewer demo allows editing of PDF metadata (Demos\PDF\PDFViewer\PDFViewer.dpr)
◼Added: Updated and improved all video demos (Demos\VideoCapture\*)
Compatibility Issues
◼Removed: The IELegacyDicomRange define (to use the pre-11.0.0 method of calculating DICOM range values) is no longer supported
◼Changed: When saving a DICOM whose pixel values were adjusted during loading, the Rescale Slope and Rescale Intercept tags are now updated rather than removed, and Window Center and Window Width are written in rescaled units. If you load with iedrSetBlackWhite and call
StretchValues yourself before saving, the Rescale tags are still removed (it is better to let ImageEn stretch the values automatically when saving)
◼Changed: Saving a DICOM loaded with iedrSetBlackWhite using
TImageEnMIO no longer changes
DICOM_Range of the frames to iedrAdjust
◼Added: Layer masks are ignored unless applied to image layers
◼Changed: The FileIndexes parameter of
ExtractFromFileZIP,
ExtractFromStreamZIP,
ExtractFromFileZIP and
ExtractFromStreamZIP is now const (TCardinalArray is a 400KB static array, which was copied onto the stack)
◼Changed:
Formatted (rich text) layers are now drawn at the document DPI (96), like other text, rather than the Windows DPI. When Windows scaling is not 100%, rich text layers will appear smaller than in previous versions (matching their appearance at 100% scaling)
◼Changed: Setting TIEBitmap.ConvertToPixelFormat or
PixelFormat to an unsupported pixel format for an image stored as a TBitmap (
Location = ieTBitmap) now raises an exception (previously nothing happened)
◼Changed:
IEVisionMatrixToMatrix now reads IEVision matrices in OpenCV order (translation in the last column). Matrices created with
MatrixToIEVisionMatrix, which uses the
TIEMatrix order, no longer convert back to the same values
◼Changed:
EncapsulateFragmentedMemory now takes the fragments parameter first: EncapsulateFragmentedMemory( fragments, fragmentsCount, rowsPerFragment, ... ). The rows are now ordered like
EncapsulateMemory (first row in memory is the bottom row, or the top row with ieboTopLeft), which is the reverse of previous versions. The parameter order was changed so existing code fails to compile and can be checked
◼Changed:
TIEMetaListView no longer shows PNG text chunks (
PNG_Chunks) in the General group by default, because they can be very large (e.g. the "workflow" field of AI generated images). To show them, set Include to True in
OnAddMetaData when MetaType is iemGeneral and DataIndex is General_Tag_PNGChunks
◼Changed: The meaning of the SelectLocked parameter (added in v15.2.0) of
TImageEnView.FindLayerAt has been reversed so it matches its name. It now defaults to True, which returns locked layers as in v15.1.1 and earlier. Pass False to get -1 when the position is over a locked and selected layer. If you passed a value for SelectLocked, invert it
◼Changed: For WIA devices,
XScaling and
YScaling now use 1.0 for 100%, as documented and as for Twain devices. Previously the raw WIA percentage was returned (e.g. 100) and setting a value had no effect. If you used 100 for 100%, use 1.0
◼Changed: For WIA devices, setting
XResolution or
YResolution now also scales the scan frame so the same area is scanned (see
SetResolution). If you set a frame in pixels with
SetItemProperty, set it after the resolution
◼Changed: Legacy Components TImageEnDBView and TImageEnDBVect are no longer installed by default
See Also
◼Complete History
◼Updating and Compatibility