larry118 Ответов: 2

Ошибка переполнения в библиотеке 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)

2 Ответов

Рейтинг:
5

larry118

Привет.

Самое простое решение-отключить переполнение в параметрах компиляции. Кроме того, был обновлен код big hug для th, так что вам даже не придется этого делать. Благодаря DavidSM64 для закрепления кода на GitHub. Уменьшение цвета-лучшее, что я видел.

Ларри


phil.o

Спасибо за информацию. Вы можете пометить вопрос как ответ, чтобы он вышел из очереди :)

Рейтинг:
2

Thomas Daniels

Вам, вероятно, повезет больше, если вы спросите у сопровождающего(ов) библиотеки, чем у нас. Попробуйте открыть вопрос на GitHub репозиторий, в Выпуски · DavidSM64/ExoQuantVB · GitHub[^].


larry118

Я думал, почта закрыта. Однако я вернулся и смог отправить сообщение. Однако здесь я всегда получаю самую лучшую помощь. Не возражаешь, если я немного оставлю это?

Thomas Daniels

Я не нахожу это проблемой вообще, что вы оставляете этот пост здесь :) Я только думаю, что это гораздо менее вероятно, что мы можем помочь вам, чем сопровождающие.

larry118

Когда-нибудь я научусь печатать на машинке.