Ciekawy problem. Natomiast zaczął bym od tego, że chyba trochę za dużo zmiennych masz naraz w eksperymencie. Tj. wydaje mi się, że testujesz naraz dwie rzeczy:
1. Re-kompresje JPG innym enkoderem z innymi ustawieniami (np. oryginalnie plik mógł być zapisany z jakością na 100%, a Twój enkoder używa jakości np. 85%).
2. Obracanie.
Zrobiłem kilka eksperymentów eliminując punkt pierwszy, tj. wyszedłem od pliku PNG/JPG, obróciłem go o 90 stopni w prawo, w lewo, i zostawiłem również wersję zapisaną normalnie, po czym skonwertowałem trzy pliki tak uzyskane na JPG/PNG. Różnica oczywiście jest (co do tego "czemu" to przejdę za chwilę), natomiast jest niewielka:
Test 1 - wejściowy PNG ze screenshotem z konsoli, okolice 1000x750px:
wyjściowy jpeg nieobrócony: 347 547 bajtów
wyjściowy jpeg obrócony w prawo o 90°: 362 779 bajtów
wyjściowy jpeg obrócony w lewo o 90°: 355 249 bajtów
skrajna różnica (abs(najmniejszy / największy - 1)): ~5%
Test 2 - wejściowy JPG z tapetą 8K z BF4:
wyjściowy jpeg nieobrócony: 5 081 563 bajtów
wyjściowy jpeg obrócony w prawo o 90°: 5 084 279 bajtów
wyjściowy jpeg obrócony w lewo o 90°: 5 064 936 bajtów
skrajna różnica (abs(najmniejszy / największy - 1)): ~0.5%
Test 3 - ten sam plik co w pierwszym teście, ale zapisany do PNG z tymi samymi ustawieniami:
wyjściowy png nieobrócony: 84 708 bajtów
wyjściowy png obrócony w prawo o 90°: 101 784 bajtów
wyjściowy png obrócony w lewo o 90°: 102 492 bajtów
skrajna różnica (abs(najmniejszy / największy - 1)): ~20%
I teraz pozostaje zagadka czemu jest jakakolwiek różnica.
Generalnie sprowadza się to do tego jak działają algorytmy kompresujące użyte w danym formacie. Konkretniej, jeśli są użyte algorytmy, których skuteczność zależy od kolejności danych, to zmiana będzie widoczna (przykłady: cała rodzina LZ77/LZW/etc, RLE). Jeśli natomiast użyte algorytmy są agnostyczne względem kolejności danych (przykład: Huffman), to różnicy nie powinno być w ogóle.
Formaty graficzne zazwyczaj korzystają z kilku algorytmów. Przykładowo, PNG w którego przypadku różnica była największa korzysta z:
1. Przede wszystkim filtrów, które wykonują proste operacje matematyczne pomiędzy kolejnymi liniami (co ma na celu zmniejszyć entropię danych jeśli linie się między sobą nie różnią znacznie).
2. DEFLATE (czyli LZ77 + Huffman).
Więc w tym wypadku zarówno filtry jak i sam DEFLATE (z uwagi na LZ77) zareagują na obrót obrazka, ponieważ dane ułożą się w zupełnie inny sposób (np. podobne pionowo linie wcale nie muszą być podobne poziomo; albo vice versa).
Jeśli chodzi o JPEG to przyznaję, że znam słabiej ten format. Generalnie grafika jest dzielona na bloki 8x8 i one są oddawane dyskretnej transformacie cosinusowej. Jak dla mnie ten etap powinien wyglądać bardzo podobnie po obrocie, głównie dlatego że de facto zawartość bloków 8x8 się nie zmieni, a sama transformata *chyba* nie zależy od kolejności danych. Natomiast potem używany jest algorytm Huffmana, któremu kolejność danych nie robi różnicy. Natomiast różnica i tak jest (choć niewielka).
Może ktoś inny ma jakiś pomysł? :)