Expand view
Topic review: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

jeeswg's script to test the IMG_GetImageSize function showed some interesting variances for some image types. I wanted to cover the image size variances found in GIF files.

Much of the appeal of the GIF format is the file size. The small(ish) file size is accomplished by using progressive compression. The first frame is created, the second frame only contains the differences of the first frame, and so on. The first frame sometimes contains the entire image size but often it is missing 1 or two pixel sizes (width and/or height). Sometimes the image size of the first frame can be dramatically different -- 20 to 30 pixel sizes different (width or height) or more. I have several GIF files where the first frame is blank.

The GIF image size is explicitly defined in the first 10 bytes of every GIF file. Without this size information, the decompression routine would not know how to correctly decompress the file. Many of the programs (including the Windows Shell program) appear to get the image size from the first image in the file instead of from the Width and Height fields that are located in the first 10 bytes of the file. I can only imagine that this is done so that the program can get other information or perform other tasks - preview image, identify color depth, etc. One of the programs on my computer (FastStone Image Viewer) does the same thing. In the window that shows a preview of all the image files in the directory, it will show what appears to be the size of the first image of the GIF file. I would wager that it uses the built-in Windows Shell program to get this information. But in the preview window for individual images, it will show the "correct" image size.

TL;DR: The size returned from the IMG_GetImageSize function is correct for GIF files. The size returned from the Windows Shell or other programs that use the size of the first image in the GIF file may not be correct.

[size=150][b]GIF Image Size[/b][/size]

[b]jeeswg[/b]'s script to test the IMG_GetImageSize function showed some interesting variances for some image types. I wanted to cover the image size variances found in GIF files.

Much of the appeal of the GIF format is the file size. The small(ish) file size is accomplished by using progressive compression. The first frame is created, the second frame only contains the differences of the first frame, and so on. The first frame sometimes contains the entire image size but often it is missing 1 or two pixel sizes (width and/or height). Sometimes the image size of the first frame can be dramatically different -- 20 to 30 pixel sizes different (width or height) or more. I have several GIF files where the first frame is blank.

[u]The GIF image size is explicitly defined in the first 10 bytes of every GIF file[/u]. Without this size information, the decompression routine would not know how to correctly decompress the file. Many of the programs (including the Windows Shell program) appear to get the image size from the first image in the file instead of from the Width and Height fields that are located in the first 10 bytes of the file. I can only imagine that this is done so that the program can get other information or perform other tasks - preview image, identify color depth, etc. One of the programs on my computer (FastStone Image Viewer) does the same thing. In the window that shows a preview of all the image files in the directory, it will show what appears to be the size of the first image of the GIF file. I would wager that it uses the built-in Windows Shell program to get this information. But in the preview window for individual images, it will show the "correct" image size.

TL;DR: The size returned from the IMG_GetImageSize function is correct for GIF files. The size returned from the Windows Shell or other programs that use the size of the first image in the GIF file may not be correct.

I downloaded the files again with the same it-works-correctly-for-me results. Weird stuff. Let me just put it out there. Is anyone getting the same results as tmplinshi? Thanks.

[quote=tmplinshi post_id=291263 time=1567723212 user_id=133]I actually tested the my uploaded file from imgur, same results.[/quote]I downloaded the files again with the same it-works-correctly-for-me results. Weird stuff. Let me just put it out there. [b]Is anyone getting the same results as tmplinshi[/b]? Thanks.

Thanks SomeGuest. This is the site that I download the few images that I have to to test the WebP format. If you (or anyone) find any others, please let me know.

[quote=SomeGuest post_id=291158 time=1567684960]https developers.google.com /speed/webp/gallery1 Broken Link for safetyhttps developers.google.com /speed/webp/gallery2 Broken Link for safety[/quote]Thanks [b]SomeGuest[/b]. This is the site that I download the few images that I have to to test the WebP format. If you (or anyone) find any others, please let me know.

I tested both of these file on my computer (Windows 7) and the function returned the correct value for both images. Obviously, you need to uninstall Windows 10 immediately!

Unless it really is a Windows 10 problem (it's not), it's possible that idiosyncrasies in the file were corrected when the images were uploaded to imgur or when I downloaded them from imgur. If possible, could you load the original problem files to a zip file and PM them to me? It would be helpful to see the files in their original condition.

Thank you for your assistance.

[quote=tmplinshi post_id=291216 time=1567706933 user_id=133]Testing for [b]GetImageSize Test - Release 6.ahk[/b][list][*]PNG files are not working, all returned 0x0 size. [url=https://i.imgur.com/bMpugjF.png]Sample.png[/url][*]The size of [url=https://i.imgur.com/17oN5pF.jpg]Sample.jpg[/url] is 1001x1334, but the script get 1334x1001.[/list]

Tested on Windows 10 64-bit, AHK v1.1.30.03 U32/U64.[/quote]I tested both of these file on my computer (Windows 7) and the function returned the correct value for both images. Obviously, you need to uninstall Windows 10 immediately! :)

Unless it really is a Windows 10 problem (it's not), it's possible that idiosyncrasies in the file were corrected when the images were uploaded to imgur or when I downloaded them from imgur. If possible, could you load the original problem files to a zip file and PM them to me? It would be helpful to see the files in their original condition.

Testing for [b]GetImageSize Test - Release 6.ahk[/b][list][*]PNG files are not working, all returned 0x0 size. [url=https://i.imgur.com/bMpugjF.png]Sample.png[/url][*]The size of [url=https://i.imgur.com/17oN5pF.jpg]Sample.jpg[/url] is 1001x1334, but the script get 1334x1001.[/list]

This pretty much covers all the extensions that I've tested with the following exceptions.

hdp, jxr - I've never found any files with this extension on my computer or in the wild. The files should have the same format as wdp but I can't be sure. If you have any files that were explicitly created with these extensions, be sure to examine the results carefully.

webp - I have a very limited number of files with this extension. If you have any of these files, be sure to examine the results carefully.

Exif - This format is supposed to have the same header as JPEG but I don't have a digital camera or any device that explicitly exports using this format. Most pictures taken from a phone or similar have Exif tags but I don't think that is same thing. If you have any files with this format, be sure to test them as well. According to Wikipedia, Exif files could have a .JPG, .TIF, or .WAV file extension.

[b]hdp, jxr[/b] - I've never found any files with this extension on my computer or in the wild. The files should have the same format as [b]wdp[/b] but I can't be sure. If you have any files that were explicitly created with these extensions, be sure to examine the results carefully.

[b]webp[/b] - I have a very limited number of files with this extension. If you have any of these files, be sure to examine the results carefully.

[b]Exif[/b] - This format is supposed to have the same header as JPEG but I don't have a digital camera or any device that explicitly exports using this format. Most pictures taken from a phone or similar have Exif tags but I don't think that is same thing. If you have any files with this format, be sure to test them as well. According to Wikipedia, Exif files could have a .JPG, .TIF, or .WAV file extension.

I wrote some code to test the IMG_GetImageSize function.Note: I had to determine which extensions to check. Do suggest any extensions that I missed.[code];[IMG_GetImageSize function];Expert Challenge: Get width and height from an image file reading as few bytes as possible. - Page 2 - AutoHotkey Community;https://autohotkey.com/boards/viewtopic.php?f=17&t=66880

Added support for icons (ICO) and standard cursors (CUR). See the function documentation for the methodology. It won't make everybody happy and it's not as fast as the other image formats but the results appear to be consistent. It also appears to be the same size returned by the AutoHotkey LoadPicture function when a size is not specified and when the icon or cursor is loaded from a stand-alone icon or cursor file. This is not true if loading an icon from a module (Ex: "shell.dll") but that's a problem for another function.

Added preliminary support for Scalable Vector Graphics (SVG). It was written using simple string matching tests. If the file is formatted correctly, it should work. However, I don't have enough test files to call this a done deal.

Added support for image handles. If a bitmap, cursor, or icon handle is passed to the function instead of a file path, the function will return the size of the image.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

With the exception of bug fixes, this is the final release of this mini-project in this forum. Additional releases (if any) will be posted in the Scripts forum.

Thanks to everyone who has taken the time and effort to download and test this function. It is appreciated. Please make a noise if you find a problem with any image format.

Added support for icons (ICO) and standard cursors (CUR). See the function documentation for the methodology. It won't make everybody happy and it's not as fast as the other image formats but the results appear to be consistent. It also appears to be the same size returned by the AutoHotkey [b]LoadPicture[/b] function when a size is not specified and when the icon or cursor is loaded from a stand-alone icon or cursor file. [i]This is not true if loading an icon from a module (Ex: "shell.dll") but that's a problem for another function.[/i]

Added preliminary support for Scalable Vector Graphics (SVG). It was written using simple string matching tests. If the file is formatted correctly, it should work. However, I don't have enough test files to call this a done deal.

Added support for image handles. If a bitmap, cursor, or icon handle is passed to the function instead of a file path, the function will return the size of the image.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

With the exception of bug fixes, this is the final release of this mini-project in this forum. Additional releases (if any) will be posted in the Scripts forum.

Thanks to everyone who has taken the time and effort to download and test this function. It is appreciated. Please make a noise if you find a problem with any image format.

OK. Added support for Animated Cursor (ANI), JPEG extended range (JPEG XR), and PiCture eXchange (PCX). I have very few test files for JPEG XR (.hdp, .jxr, and .wdp file extensions) so testing of this format would be appreciated.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I'm working on icons and standard cursors. The code is pretty much ready-to-go but I'm not entirely satisfied with the logic for determining which size is returned when there are multiple image sizes.

Feedback would be appreciated, especially if you find a problem. Thank you for your assistance.

OK. Added support for Animated Cursor (ANI), JPEG extended range (JPEG XR), and PiCture eXchange (PCX). I have very few test files for JPEG XR (.hdp, .jxr, and .wdp file extensions) so testing of this format would be appreciated.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I'm working on icons and standard cursors. The code is pretty much ready-to-go but I'm not entirely satisfied with the logic for determining which size is returned when there are multiple image sizes.

Feedback would be appreciated, especially if you find a problem. Thank you for your assistance.

Re. icons. The easiest to get should be default. But max (and perhaps min) seem like good options.

Re. jxr:
- The jxr/wdp (JPEG XR) format seems to be the standard for (amongst others): telegraph.co.uk and washingtonpost.com (at least on Internet Explorer).
- Of downloaded images, I'm seeing these by frequency (and no other file types):
- jpg/png/(jpeg=jpg)/gif/svg/jxr/webp/bmp/(wdp=jxr).
- Hopefully, since it's a JPEG format, the jxr logic should be similar to some of your existing jpeg logic.

Re. icons. The easiest to get should be default. But max (and perhaps min) seem like good options.

Re. jxr:- The jxr/wdp (JPEG XR) format seems to be the standard for (amongst others): telegraph.co.uk and washingtonpost.com (at least on Internet Explorer).- Of downloaded images, I'm seeing these by frequency (and no other file types):- jpg/png/(jpeg=jpg)/gif/svg/jxr/webp/bmp/(wdp=jxr).- Hopefully, since it's a JPEG format, the jxr logic should be similar to some of your existing jpeg logic.

Just to keep you up to date, I've been working on adding icons and cursors but I knew from the get-go that there would be issues because these file types can hold multiple images with multiple sizes. How can a "GetImageSize" function return a single image size if the file contains images with more than one size?

In the order of complexity or the number of problems...

Animated Cursors
Animated cursor files (Ex: "MyAnimatedCursor.ani") can theoretically include multiple image sizes but they usually (always?) only have one size so it's safe (or at least it's consistent) to return the size of the first image in the file.

Microsoft system functions that load cursors are not consistent when requested to load a cursor and specific size is not specified. The LoadImage system function will get the first cursor in the file whereas the LoadCursorFromFile system function will get the 32x32 cursor if it exist, otherwise it will get the first image in the file. ##### Check that. This may not be true. The function may return a 32x32 image regardless of what size cursors that are in the file. I need to test it to be sure.

The AutoHotkey LoadPicture command appears to use the LoadImage (or similar) system function for stand-alone cursor files. The first cursor in the file is loaded if no size is specified.

There is no "correct" answer but the "best" and certainly fastest answer might be to return the size of the first cursor in the file. The results would match the LoadImage system function and the AutoHotkey LoadPicture command when no size is specified.

IconsPlease excuse the rambling style of this topic. Too many considerations and too little time to format it into a concise thesis.

Icon files (Ex: "MyIcon.ico") can and do include multiple image sizes. Asking for the icon's image size can be a fool's errand.

With a file that has multiple icon sizes, is there one icon size that should be returned when calling a "GetIconSize" function? The answer has to be Yes because you would except to get a size if the file had only one icon. Wouldn't you expect something if the file has multiple icons? Well then, what size should should be returned then? The best or most logical answer is probably the size of the default icon.

So... What the heck is the default icon, and how does one determine which icon in a group of icons is the default? First of all, there is no such thing as a "default" icon. Well, not officially. However, "default" is an appropriate term to describe the icon that is returned when a size is not specified. In other words, when the specified Width and Height values are zero (0). The system functions designed to load an icon from a stand-alone file (primarily LoadImage) all return the same icon when no size is specified so they provide a good template for determining the default icon. The bad news is the selection criteria includes factors that can change depending on the current video mode. The first icon that works best with the current video mode becomes the default icon.

There are other basic considerations. The image size is stored in 1-byte fields. This allows for an image size from 0 to 255. In the past (before Vista?), 0 always indicated an image size of 256 but now, 0 means any size over 255. Assuming 256 is a fairly safe bet but it not a sure thing. The only way to know for sure is to get the image size directly from the bitmap or PNG image. This is not a quick or inexpensive task for a script.

OK, I'm getting lost. Let me try to regroup.

The function could (and should) include code to deal with all of these issues but I'm thinking that I don't want to write it. Even if I did write it, the entire icon file would need to read in many cases so it wouldn't be any faster than calling a system function to load the icon.

The best and most efficient solution might be a southern engineered solution. If the file contains a single icon and the icon size is between 1 and 255, return that size. Otherwise, call a system function (probably LoadImage) to load the default (or only) icon and return the size of that icon. There is extra code needed to get the size of loaded icon but it's not too bad. This solution certainly won't be as fast as the other image formats but it may be the way to go.

Final Thoughts
Them be my thoughts. I would appreciate your thoughts on these issues.

Just to keep you up to date, I've been working on adding icons and cursors but I knew from the get-go that there would be issues because these file types can hold multiple images with multiple sizes. How can a "GetImageSize" function return a single image size if the file contains images with more than one size?

In the order of complexity or the number of problems...

[color=Navy][size=150][b]Animated Cursors[/b][/size][/color]Animated cursor files (Ex: "MyAnimatedCursor.ani") can theoretically include multiple image sizes but they usually (always?) only have one size so it's safe (or at least it's consistent) to return the size of the first image in the file.

[color=Navy][size=150][b]Standard Cursors[/b][/size][/color]Standard cursor files (Ex: "MyCursor.cur") can and do include multiple image sizes.

Microsoft system functions that load cursors are not consistent when requested to load a cursor and specific size is not specified. The [b]LoadImage[/b] system function will get the first cursor in the file whereas the [b]LoadCursorFromFile[/b] system function will get the 32x32 cursor if it exist, otherwise it will get the first image in the file. ##### Check that. This may not be true. The function may return a 32x32 image regardless of what size cursors that are in the file. I need to test it to be sure.

The AutoHotkey [b]LoadPicture[/b] command appears to use the [b]LoadImage[/b] (or similar) system function for stand-alone cursor files. The first cursor in the file is loaded if no size is specified.

There is no "correct" answer but the "best" and certainly fastest answer might be to return the size of the first cursor in the file. The results would match the [b]LoadImage[/b] system function and the AutoHotkey [b]LoadPicture[/b] command when no size is specified.

[color=Navy][size=150][b]Icons[/b][/size][/color][i]Please excuse the rambling style of this topic. Too many considerations and too little time to format it into a concise thesis.[/i]Icon files (Ex: "MyIcon.ico") can and do include multiple image sizes. Asking for the icon's image size can be a fool's errand.

With a file that has multiple icon sizes, is there one icon size that should be returned when calling a "GetIconSize" function? The answer has to be Yes because you would except to get a size if the file had only one icon. Wouldn't you expect [i]something[/i] if the file has multiple icons? Well then, what size should should be returned then? The best or most logical answer is probably the size of the default icon.

So... What the heck is the [b]default[/b] icon, and how does one determine which icon in a group of icons is the default? First of all, there is no such thing as a "default" icon. Well, not officially. However, "default" is an appropriate term to describe the icon that is returned when a size is not specified. In other words, when the specified Width and Height values are zero (0). The system functions designed to load an icon from a stand-alone file (primarily [b]LoadImage[/b]) all return the same icon when no size is specified so they provide a good template for determining the default icon. The bad news is the selection criteria includes factors that can change depending on the current video mode. The first icon that works best with the current video mode becomes the default icon.

There are other basic considerations. The image size is stored in 1-byte fields. This allows for an image size from 0 to 255. In the past (before Vista?), 0 always indicated an image size of 256 but now, 0 means any size over 255. Assuming 256 is a fairly safe bet but it not a sure thing. The only way to know for sure is to get the image size directly from the bitmap or PNG image. This is not a quick or inexpensive task for a script.

[i]OK, I'm getting lost. Let me try to regroup.[/i]

The function could (and should) include code to deal with all of these issues but I'm thinking that I don't want to write it. Even if I did write it, the entire icon file would need to read in many cases so it wouldn't be any faster than calling a system function to load the icon.

The best and most efficient solution might be a southern engineered solution. If the file contains a single icon and the icon size is between 1 and 255, return that size. Otherwise, call a system function (probably [b]LoadImage[/b]) to load the default (or only) icon and return the size of that icon. There is extra code needed to get the size of loaded icon but it's not too bad. This solution certainly won't be as fast as the other image formats but it may be the way to go.

[color=Navy][size=150][b]Final Thoughts[/b][/size][/color]Them be my thoughts. I would appreciate your thoughts on these issues.

OK. The bugs in the TIFF format have been fixed. The changes primarily fix bugs in the code for the big endian TIFF format but the integrity for both TIFF formats has been improved/fixed.

Thanks to SomeGuest for providing a link to a bunch of TIFF files. Not only did these files help to identify the bugs in the code, they helped to identify that not all programs can read TIFF file correctly, especially the older TIFF files. AutoHotkey (using GDI+) could not read more than a dozen of the files. My image viewer could read most but not all.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I'm still looking for EMF and WMF files for testing. If you have or find any, please make a noise.

Feedback would be appreciated, especially if find a problem. Thank you for your assistance.

OK. The bugs in the TIFF format have been fixed. The changes primarily fix bugs in the code for the big endian TIFF format but the integrity for both TIFF formats has been improved/fixed.

Thanks to [b]SomeGuest[/b] for providing a link to a bunch of TIFF files. Not only did these files help to identify the bugs in the code, they helped to identify that not all programs can read TIFF file correctly, especially the older TIFF files. AutoHotkey (using GDI+) could not read more than a dozen of the files. My image viewer could read most but not all.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I'm still looking for EMF and WMF files for testing. If you have or find any, please make a noise.

Feedback would be appreciated, especially if find a problem. Thank you for your assistance.

OK. The accuracy problem for EMF has been fixed. However, the calculation was adjusted to match GDI+. See the function documentation for more information.

As before, I've attached a near-ready-to run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I have very few EMF and WMF files for testing. Some of the EMF files were generated from other file types just to create more EMF files to test. I fear that my test results for EMF and WMF data is skewed and doesn't really represent what really out there. If you have any EMF and/or WMF files, please include those files in your tests.

I'm also still looking for big endian TIFF files. These would be old TIFF files created on Motorola or IBM chips. Stuff created on an old Mac for example. The files will have "MM" in the first two bytes of the file.

Feedback would be appreciated, especially if you find a problem. Thank you for your assistance.

OK. The accuracy problem for EMF has been fixed. However, the calculation was adjusted to match GDI+. See the function documentation for more information.

As before, I've attached a near-ready-to run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I have very few EMF and WMF files for testing. Some of the EMF files were generated from other file types just to create more EMF files to test. I fear that my test results for EMF and WMF data is skewed and doesn't really represent what really out there. If you have any EMF and/or WMF files, please include those files in your tests.

I'm also still looking for big endian TIFF files. These would be old TIFF files created on Motorola or IBM chips. Stuff created on an old Mac for example. The files will have "MM" in the first two bytes of the file.

Feedback would be appreciated, especially if you find a problem. Thank you for your assistance.