Fixed [1.3B2] EXIF Rotation of large image

shorepower

Active member
Uploading large image to post will fail if picture is rotated. Error happens when upload is at 100%. Non-rotated pictures of same size works.

Error replicated both on my own system (running PHP built-in GD image library and image size set to 800x600) and at Xenforo.com site. Uploading same picture on 1.2.4 works (no rotation)

Sample picture in Dropbox (and yes, I also considered picture quality as the reason for the failure of uploading the picture :) )
 
Uploaded files are first resized based on the maximum physical dimensions (pixels) set in the ACP -> Options -> Attachments: Maximum Attachment Image Dimensions. If the resized image is below the maximum file size (KB) limit, then it will be allowed.

I'm just guessing here but with rotated images, if they are first changed to the correct orientation and re-saved, this may increase the file size, causing the image to be rejected due to being too large.

Having said that, I have just tested that image on my local and I was able to upload it with a max file size of 1.5MB and no dimensions set.
 
Uploaded files are first resized based on the maximum physical dimensions (pixels) set in the ACP -> Options -> Attachments: Maximum Attachment Image Dimensions. If the resized image is below the maximum file size (KB) limit, then it will be allowed.

I'm just guessing here but with rotated images, if they are first changed to the correct orientation and re-saved, this may increase the file size, causing the image to be rejected due to being too large.

Having said that, I have just tested that image on my local and I was able to upload it with a max file size of 1.5MB and no dimensions set.

Made same test on my own installation. With no dimension set the picture will up-load and re-orientate correctly. This picture is originally around 15M (4592*3448) pixels so below the threshold of 20M. As stated, tested to up-load to xenforo.com and also got error on this system.

Question is if the threshold will be lower with rotated pictures and if so, what will be the maximum size. Error message do not state that the picture is to large, just that the up-load failed.
 
I can see the error being generated here in the ACP.
Is the file you linked to in Dropbox the same one you tried to upload here?
 
So I made a number of tests, resizing the image and this is the result. Not sure about the settings on Xenforo.com but it seems to be same problems with this forum as my own test forum. In the table, success=uploaded the picture and it got correctly oriented. Fail=upload goes to 100% after which the process fails.

My own test server (running PHP built-in GD image library and image size set to 800x600))

Image size Result
4592*3548 Fail
3864*2901 Success
3644*2736 Success

My own test server (running PHP built-in GD image library and image size set to 2048*1536)

Image size Result
4592*3548 Fail

My own test server (running PHP built-in GD image library and no dimension set)

Image size Result
4592*3548 Success

Xenforo.com forum

Image size Result
4592*3548 Fail
3864*2901 Success
 
Last edited:
I'm not entirely convinced this is a bug.

This is more down to various memory limits.

XenForo does a check based on the multiplication of the width x height of an image. The default limit for this is 20000000. If the pixel count is below that value, XenForo will attempt to resize it (and indeed the same check is used for rotation too). If the pixel count is above that limit, it will be skipped. It will still be uploaded but it will not be rotated or resized.

The solution is simply to either provide more resources to the server or more simply, change the limit in the config.

In config.php add something like:
PHP:
$config['maxImageResizePixelCount'] = 16000000;
 
I'm not entirely convinced this is a bug.

This is more down to various memory limits.

XenForo does a check based on the multiplication of the width x height of an image. The default limit for this is 20000000. If the pixel count is below that value, XenForo will attempt to resize it (and indeed the same check is used for rotation too). If the pixel count is above that limit, it will be skipped. It will still be uploaded but it will not be rotated or resized.

The solution is simply to either provide more resources to the server or more simply, change the limit in the config.

In config.php add something like:
PHP:
$config['maxImageResizePixelCount'] = 16000000;


Yes, I'm aware but the image is below the default limit of 20M pixels. If you try to upload a image above 20M you will get an error message telling that the picture is to large.

Looking on the test cases I supplied, uploading the same image with no scaling involved will not cause a problem. It's neither a problem uploading the same image to 1.2.4.

So the EXIF rotation creates some sort of memory? problem when the image is over a certain size. You will not get an error message telling you that the image is to large.
Uploading a image of similar size that do not need to be rotated works perfectly in 1.3B2.

I consider this as a bug. I do not know the resolution

* Error in EXIF rotation handling
* Implementation of new error message
* New default lower limit (based on my testing it needs to be below 15M)
* Tweaking of system parameters
* ?

I entered this report to make sure the developers are aware of the problem. I'm not at this stage trying to solve it in my production system as I'm not running 1.3B2 other than for test purposes.
 
Yes, exactly. The image is below the pixel limit, but that is just an arbitrary limit. It doesn't imply that your server is capable of allocating that amount of memory to the task of rotating and then resizing the image. And that is why the limit is there. To be clear, it's different from the attachmentMaxFileSize limit. The limit I'm talking about is set in the config.php file and cannot be set in the Admin CP.

Although a default lower limit would solve your problem, it would be unfair to impose that limit on servers that are much more capable by default. So the resolution is still to adjust that limit yourself in your config file. Your testing has shown it needs to be below 15M so you should adjust your config.php file to include:
PHP:
$config['maxImageResizePixelCount'] = 15000000;

The developers are aware of "the problem" that's why the limit exists as a configurable option. It actually used to be statically set at 16000000 IIRC. It is more recent that it has become a configurable option.

All being said, it might be better for the default limit to be the same as it was in version < 1.2 to ensure a greater chance of compatibility.
 
Basically, the issue is that to do EXIF rotation on a full image we actually need enough memory for 2 of the images. This doesn't come up as significantly for resizing because the second image is much smaller, but the concept still applies there. Doing any image manipulation that needs a new canvas (rotation and the other EXIF transforms) will require that there are temporarily 2 canvases in memory.

GD basically uses 5 bytes per pixel. So roughly, a 20 megapixel image will take about 100MB of memory while it's being worked on. There's nothing we can do about this. I suspect Imagick is similar, but because its likely using its own malloc function, the memory won't contribute towards PHP's memory limit.

So, I've fixed this in two ways:
  1. When loading an image into GD, we make sure there's an available memory buffer (if possible) to handle the temporary memory allocation.
  2. The rotation happens after the resize, if you choose to set a max size.
 
Top Bottom