La cámara posee código hecho en Java del cual se pueden obtener los .jar para emplearlos en un código de prueba.
Consultamos entonces a los fabricantes: nos responden que la compañía cambió de manos. Consultamos a los nuevos responsables y obtenemos como información que tenemos tres caminos:
- utilizar una API a nivel registro con la cual se accede a la cámara enviando códigos de operación
- revisar los archivos minivis.jar y minivis.dll
- comprar otra cámara o adquirir el nuevo software.
Luego de varios días de revisar los resultados del Java Decompiler. Obtenemos una sucesión de pasos que permite obtener las imágenes con resultados bastante malos:
- Snapshots tomados: 200
- fps entre Snapshots: 2500
- Tiempo Total: 7800ms (sólo en la transferencia, ya que la toma de imágenes se debe hacer previa a la este paso)
- Tiempo Promedio: 39ms (es decir, 25 fps)
Pero entonces surge una duda ¿Y si los tiempos son lentos por estar utilizando java? Para tratar de falsear esta teoría, recurrimos a código C++ que intente levantar las DLLs directamente y no utilizar minivis.jar. Nuevamente tenemos que decompilar, en este caso decompilamos el archivo minivis.dll y hacemos un matcheo contra lo observado en minivis.jar. Igualmente, debemos notar que ambos archivos se comunican gracias a que se empleó JNI en C++. Lamentablemente esto simplemente complica la tarea de decompilación y reuso de la DLL original.
Con una sola prueba de concepto nos queda claro que ese no es el mejor camino:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention
Aquí el código Java:
1: class DummyConsumer implements CallbackConsumer {
2: public void modeChanged(int paramInt){
3: }4: public void statusChanged(int paramInt) {
5: }6: public void shutterChanged(boolean paramBoolean, short paramShort) {
7: } 8: } 9: 10: public class Application {
11: public static void main(String[] arguments) {
12: int numberOfImages = Integer.parseInt(arguments[0]);
13: 14: MinivisFactory factory = MinivisFactory.getInstance();15: try {
16: factory.discover(); 17: TypedNetAddress[] addresses = factory.getKnownDevices();18: String mac = addresses.length > 0 ? addresses[0].getEntryName() : "00-50-C2-1D-7E-AB";
19: DummyConsumer callbackConsumer = new DummyConsumer();
20: Proxy camera = factory.getCamera(mac, callbackConsumer);21: try {
22: camera.connect();23: try {
24: takeSnapshots(camera, numberOfImages, debug); 25: } 26: finally {
27: camera.disconnect(); 28: } 29: }30: finally {
31: camera.release(); 32: } 33: }34: catch(Exception e) {
35: e.printStackTrace(); 36: } 37: }38: private static void takeSnapshots(Proxy camera, int numberOfImages, boolean debug) throws IOException, MDriverException, Exception {
39: camera.setMode(4); //0 LIVE 1 RECORD 2 TRIGGERED 3 DRAM 4 LOWLIGHT
40: camera.trigger(); 41: 42: //missing code here: wait for trigger to finish
43: 44: MFrameInfo frameInfo = new MFrameInfo();
45: for(int i = 0; i < numberOfImages; ++i) {
46: byte[] frameBytes = camera.getFrame(-1, -1 , frameInfo);
47: } 48: } 49: }Aquí el código C++:
1: 2: #include "stdafx.h"
3: #include <iostream> 4: 5: 6: int _tmain(int argc, _TCHAR* argv[])
7: {8: HMODULE hMod = LoadLibrary("minivis.dll");
9: typedef long (*MinivisFactory_Create)();
10: typedef long (*GetCamera)(long, char*, void*);
11: MinivisFactory_Create n_MinivisFactory_Create = (MinivisFactory_Create)GetProcAdress("_Java_com_artho_visart_plugins_minivis_internal_jni_MinivisFactory_n_1MinivisFactory_1Create@8");
12: GetCamera n_GetCamera = (GetCamera)GetProcAdress("_Java_com_artho_visart_plugins_minivis_internal_jni_MinivisFactory_n_1GetCamera@24");
13: 14: 15: long adapterPtr = n_MinivisFactory_Create();
16: void* consumer = NULL;
17: long pointer = n_GetCamera(adapterPtr, "00-50-C2-1D-7E-AB", consumer);
18: 19: std::cout << "Camera pointer:" << pointer << std::endl;
20: std::cout << "Press any key to continue..." << std::endl;
21: char character;
22: std::cin >> character;23: return 0;
24: }