Я пытаюсь добиться следующего:
1) У меня есть массив байтов на стороне java, который представляет изображение.
2) Мне нужно предоставить доступ к моему родному коду.
3) Собственный код декодирует это изображение с помощью GraphicsMagick и создает кучу миниатюр, вызывая resize. Он также вычисляет перцепционный хеш изображения, которое является либо вектором, либо массивом unint8_t.
4) Как только я верну эти данные обратно на сторону Java, их будут читать разные потоки. Миниатюры будут загружены в какой-либо внешний сервис хранения через HTTP.
Мои вопросы:
1) Какой самый эффективный способ передать байты из Java в мой собственный код? У меня есть доступ к нему как к массиву байтов. Я не вижу особого преимущества в передаче его в виде буфера байтов (обертывания этого массива байтов) по сравнению с массивом байтов здесь.
2) Каков наилучший способ вернуть эти эскизы и перцепционный хэш обратно в код Java? Я подумал о нескольких вариантах:
(i) Я мог бы выделить буфер байтов в Java, а затем передать его моему собственному методу. Собственный метод может затем записать в него и установить ограничение после того, как это будет сделано, и вернуть количество записанных байтов или какое-либо логическое значение, указывающее на успех. Затем я мог бы нарезать и нарезать байтовый буфер, чтобы извлечь отдельные эскизы и перцепционный хеш и передать их в разные потоки, которые будут загружать эскизы. Проблема с этим подходом в том, что я не знаю, какой размер выделить. Необходимый размер будет зависеть от размера сгенерированных миниатюр, который я не знаю заранее, и количества миниатюр (я знаю это заранее).
(ii) Я мог бы также выделить буфер байтов в собственном коде, как только я знаю необходимый размер. Я мог бы записать свои большие двоичные объекты в нужный регион на основе моего пользовательского протокола упаковки и вернуть этот байтовый буфер. И (i), и (ii) кажутся сложными из-за пользовательского протокола упаковки, который должен указывать длину каждого эскиза и воспринимаемый хэш.
(iii) Определите класс Java, который имеет поля для эскизов: массив байтовых буферов и перцептивный хеш: массив байтов. Я мог бы выделить байтовые буферы в нативном коде, если бы знал точные необходимые размеры. Затем я могу записать байты из большого двоичного объекта GraphicsMagick на прямой адрес каждого байтового буфера. Я предполагаю, что есть также какой-то метод для установки количества байтов, записанных в буфер байтов, чтобы код Java знал, насколько велики буферы байтов. После того, как байтовые буферы установлены, я могу заполнить свой объект Java и вернуть его. По сравнению с (i) и (ii) здесь я создаю больше байтовых буферов, а также объект Java, но избегаю сложности пользовательского протокола. Обоснование (i), (ii) и (iii) — учитывая, что единственное, что я делаю с этими миниатюрами, — это загружаю их, я надеялся сохранить дополнительную копию с байтовыми буферами (вместо массива байтов) при их загрузке через NIO. .
(iv) Определите класс Java, который имеет массив байтовых массивов (вместо байтовых буферов) для эскизов и байтовый массив для перцептивного хэша. Я создаю эти массивы Java в собственном коде и копирую байты из большого двоичного объекта GraphicsMagick с помощью SetByteArrayRegion. Недостатком по сравнению с предыдущими методами является то, что теперь при копировании этого массива байтов из кучи в некоторый прямой буфер при его загрузке будет еще одна копия в земле Java. Не уверен, что я бы сохранил что-либо с точки зрения сложности и (iii) здесь.
Любой совет был бы потрясающим.
РЕДАКТИРОВАТЬ: @main предложил интересное решение. Я редактирую свой вопрос, чтобы следить за этим вариантом. Если бы я хотел обернуть собственную память в DirectBuffer, как предлагает @main, как бы я узнал, когда я могу безопасно освободить собственную память?