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