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: }