Ошибка переполнения в библиотеке exoquant color reduction из github
Существует библиотека сокращения цвета под названием ExoQuant, написанная Деннисом Рэнке из Массачусетского технологического института. Существуют версии,доступные в JavaScript,C#, VB и Python. Я экспериментировал с каждой библиотекой цветопередачи, которую смог найти. Различные алгоритмы лучше работают на разных типах изображений. Когда я закончу, я надеюсь написать обзор с примерами, потому что существует серьезный недостаток информации об использовании всех этих библиотек. Но они свободны. Так что огромное спасибо всем, кто помогает таким "проблемным" разработчикам, как я.
Во всяком случае, библиотека ExoQuant основана на алгоритме цветового Квантователя Сяолиня Ву. Алгоритм лучше всего работает на изображениях, которые вызывают у меня определенные проблемы. Я бы с удовольствием загрузил изображения, но не вижу способа сделать это здесь. Если кто - то протянет руку, я буду счастлив поделиться ими. Они не являются собственностью, они просто дают квантователям довольно много агиты. Даже если цветовой Квант равен 48 или 64.
ссылка на библиотеки есть https://github.com/DavidSM64/ExoQuantVB-да. Там же есть и другие ссылки на c#, javascript и python.
Вот проблема, насколько я могу ее описать. При хэшировании каждого пикселя, хранящегося в потоке byte (), происходит переполнение по любому передаваемому ему цвету на третьей строке подпрограммы:
Private Function MakeHash(ByVal rgba As Uinteger) As UInteger Try '1 rgba -= (rgba >> 13) Or (rgba << 19) '2 rgba -= (rgba >> 13) Or (rgba << 19) '3 rgba -= (rgba >> 13) Or (rgba << 19) rgba -= (rgba >> 13) Or (rgba << 19) rgba -= (rgba >> 13) Or (rgba << 19) rgba = rgba And (EXQ_HASH_SIZE - 1) Return rgba Catch ex As Exception MessageBox.Show("ExoQuant.MakeHash: " + ex.Message + " " + ex.StackTrace) Return 255 End Try End Function
Функция вызывается из:
Public Sub Feed(ByVal pData As Byte()) Dim channelMask As Byte = &HFF00 >> pExq.numBitsPerChannel Dim nPixels As Integer = Int(pData.Length / 4) For i As Integer = 0 To nPixels - 1 Dim r As Byte = pData(i * 4 + 0), g As Byte = pData(i * 4 + 1), b As Byte = pData(i * 4 + 2), a As Byte = pData(i * 4 + 3) 'If pdata(i * 4 + 3) = 0 Then ' a = 255 'Else ' a = pData(i * 4 + 3) 'End If Dim hash As UInteger = MakeHash(ToRGBA(r, g, b, a)) Dim pCur As ExqHistogramEntry = pExq.pHash(hash) While pCur IsNot Nothing AndAlso (pCur.ored <> r OrElse pCur.ogreen <> g OrElse pCur.oblue <> b OrElse pCur.oalpha <> a) pCur = pCur.pNextInHash End While If pCur IsNot Nothing Then pCur.num += 1 Else pCur = New ExqHistogramEntry() pCur.pNextInHash = pExq.pHash(hash) pExq.pHash(hash) = pCur pCur.ored = r pCur.ogreen = g pCur.oblue = b pCur.oalpha = a r = r And channelMask g = g And channelMask b = b And channelMask pCur.color.r = r / 255.0F * SCALE_R pCur.color.g = g / 255.0F * SCALE_G pCur.color.b = b / 255.0F * SCALE_B pCur.color.a = a / 255.0F * SCALE_A If pExq.transparency Then pCur.color.r *= pCur.color.a pCur.color.g *= pCur.color.a pCur.color.b *= pCur.color.a End If pCur.num = 1 pCur.palIndex = -1 pCur.ditherScale.r = -1 pCur.ditherScale.g = -1 pCur.ditherScale.b = -1 pCur.ditherScale.a = -1 pCur.ditherIndex(0) = -1 pCur.ditherIndex(1) = -1 pCur.ditherIndex(2) = -1 pCur.ditherIndex(3) = -1 End If Next End Sub
Функция ToRGBA такова:
Private Function ToRGBA(ByVal r As UInteger, ByVal g As UInteger, ByVal b As UInteger, ByVal a As UInteger) As UInteger Return r Or (g << 8) Or (b << 16) Or (a << 24) End Function
Что я уже пробовал:
Сообщение об ошибке из строки 3 выглядит следующим образом:
В результате выполнения арифметической операции переполнение.
Я пробовал отправлять различные байт-потоки цвета как в 24-битных, так и в 32-битных изображениях. Я установил альфа-канал на 0,128 и 256. Я пробовал играть со сдвигом битов, но не могу сказать, что действительно понимаю, что делает рекурсия сдвига битов в следующем примере. Существует также недостаток документации и примеров для логического переключения ИТ в vb .net. Я тоже нашел c# довольно запутанным.
Любая помощь будет оценена по достоинству.
Ссылки на gitHub
rgba -= (rgba >> 13) Or (rgba << 19) rgba -= (rgba >> 13) Or (rgba << 19) rgba -= (rgba >> 13) Or (rgba << 19) ' blows up here value of rgba before this line is 61151760 rgba -= (rgba >> 13) Or (rgba << 19) rgba -= (rgba >> 13) Or (rgba << 19) rgba = rgba And (EXQ_HASH_SIZE - 1)