OJODIGITAL |
|
|
|
| perfectRAW/perfectBLEND Foro para tratar todo lo relacionado con estos dos programas basados en DCRaw para el revelado de imágenes RAW y el blending de imágenes para aumentar su rango dinámico |
![]() |
| Publicidad |
|
||||
|
Yo desde este fin de semana reduciré mi rendimiento a más o menos la mitad. Espero que aún así el proyecto pueda seguir adelante.
Un saludo: |
|
||||
|
Vale me parece bien, que esto va demasiado rápido y no es cuestión de agobiarse. Este finde tengo pensado escribir algún artículo nuevo pero también empezar a mirar lo del balance de blancos temp/matiz. Quiero instalarme el UFRAW para ver si los multiplicadores del balance de blancos para una pareja temp/matiz dependen o no de la cámara referida. Si son independientes (me da que no va a ser así pero bueno) sacaré una tabla de parejas (temperatura,matiz)->(R/G,B/G) a pelo y se acabó.
__________________
"En ocasiones veo halos." Canon EOS 350D | EOS 300 | 10-22 | 24-70 f2.8L | 70-200 f4L | 300 f4L IS http://www.guillermoluijk.com para suscribirte pulsa aquí Última edición por _GUI_; 30-may-2008 a las 13:09. |
|
||||
|
oye, y si poneis un nº de cuenta y colaboramos ? =P
1 euro por forero sería un paston para que podais trabajar comodamente cenando gratis o algo ![]() |
|
||||
|
Cita:
Un saludo: |
|
|||
|
Bien, me parece que está bastante claro lo que tenemos que ir haciendo próximamente.
Yo esta última semana también he bajado algo el tiempo dedicado. El fin de semana no he estado en casa, así que no le he dedicado mucho. Mañana le podré dedicar tiempo desde media tarde, pero se me vienen encima unos días con menos tiempo libre (obras en casa, se acercan exámenes y tengo un par de cursos en ciernes). De todas formas podré dedicarle tiempo por la tarde/noche. Por cierto, que va haciéndose necesario definir una estructura de paso entre las diferentes partes de la aplicación que almacena los buffers, los parámetros de revelado, etc. Digo estructura porque debe de poder ser accesible desde las funciones en C/C++. Las funciones en C que se llaman desde C# deberían de recibir un puntero a dicha estructura como primer parámetro. Así tendrán a su disposición toda la información y además no habrá el problema con las variables globales, que no se portan nada bien con la programación multihilo (evidentemente dcraw tendrá que seguir como está). Todo lo que una función necesite guardar entre una llamada y otra o para su uso posterior en otras funciones, debería de ser almacenado aquí. Incluso se podría definir más de una estructura: -Una para los parámetros de revelado (DevelopingParams). -Otra para las opciones de visualización del usuario (número y modo de las vistas, chivato de altas luces activado, buffer mostrado, etc). (VisualizationOptions). -La ya existente de DCRaw para pasar información a las DCRawDLL Luego metemos variables de ese tipo en una estructura que lo englobe todo: struct ImageUniverse { DCRawOptions rawOpt; DevelopingParams devParams; VisualizationOptions visOpt; Bitmap buffer16; Bitmap buffer8; } Efectivamente habrá que ver cómo se comporta al pasar campos de texto entre C# y C (parece que al menos en Vista64 da problemas) aunque la mayor parte de los parámetros no serán de tipo String; Bueno el contenido concreto habría que definirlo con detalle, pero creo que es clara la necesidad de poder intercambiar fácilmente información sobre el estado de la imagen entre todos los elementos de la aplicación. Última edición por ariznaf; 01-jun-2008 a las 22:58. |
|
||||
|
Cita:
Lo que entiendo que tú propones es tener una única estructura con toda la información necesaria y pasarla a través de un puntero a C y C++ y acceder globalmente a ella desde C#, ¿no? Supongo que dentro de esa estructura habría dos subestructuras para los revelados y sus parámetros. Cita:
Cita:
Código:
function(PARAMS *structGlobalAppState, char **arrayGlobalAppStrings, ...); Éstas son las que hay ahora: Código:
// Image info struct
// DNG version and camera white balance coef. still missing
typedef struct DCRAW_ImageInfo
{
char *timestamp;
char *camera_make;
char *camera_model;
char *artist;
int iso_speed;
float shutter;
float aperture;
float focal_length;
float aspect_ratio;
int raw_width;
int raw_height;
int in_width;
int in_height;
int out_width;
int out_height;
int raw_colors;
char *filter_pattern;
}IMAGE_INFO;
// Struct for passing parameters to the development process
// * implemented in perfectRAW
typedef struct DCRAW_Parameters
{
float threshold; // -n -> buffer 2
double aber[4]; // -r -> buffer 2
int use_auto_wb; // -a -> buffer 2
int use_camera_wb; // -w -> buffer 2
unsigned greybox[4]; // -A -> buffer 2
int user_black; // -K -> buffer 2 *
int user_sat; // -S -> buffer 2 *
int test_pattern; // -> buffer 2
int level_greens; // -l -> buffer 2
int user_qual; // -q -> buffer 3
int four_color_rgb; // -f -> buffer 3
int med_passes; // -m -> buffer 4
int highlight; // -H -> buffer 4 *
int output_color; // -o -> buffer 5
int use_fuji_rotate; // -J -> buffer 5
float user_gamma; // -g -> buffer 5
float exposure; // -> buffer 4 *
float preserve; // -> buffer 4 *
}DLL_PARAMETERS;
// Struct for saving and restoring DLL state
typedef struct DCRAW_State
{
int valid;
int filters;
int colors;
int shrink;
int half_size;
int mix_green;
int width;
int height;
int iwidth;
int iheight;
int top_margin;
int left_margin;
int raw_color;
int maximum;
int black;
float cam_mul[4];
float pre_mul[4];
float cmatrix[3][4];
float rgb_cam[3][4];
unsigned short (*buffer)[4];
}DLL_STATE;
Última edición por ManuelLlorens; 02-jun-2008 a las 18:47. |
|
|||
|
Sí, Manuel, lo que proponía es que esas estructuras se incluyan dentro de otra que sea la que se pase a los controles PerfectView y de ahí a las llamadas en C.
Las funciones en C que sólo necesiten una de las subestructuras, se les podrá pasar un puntero a las mismas. En la Super Struct (por llamarla de alguna manera) habrá que almacenar también el buffer de 16 bits de salida (con espacio de color y gamma) y el de 8 bits del monitor (bueno un puntero a los buffers) para poder accederlos desde las funciones que interese. Esa era la idea para no tener que andar pasando un montón de parámetros. Queda el problema con los char * y la función dcraw. No creo que sea problema en las funciones programadas por nosotros porque se podrán compilar como unicode, pero habrá que probarlo a ver qué pasa. La verdad es que todo ese tema es un quebradero de cabeza, pero que le vamos a hacer, es lo que hay. Seguramente en algún momento encontraremos la solución, una opción de compilación o algo que haga que funcione correctamente, pero mientras tanto... Sólo la estructura de dcraw parece tener problemas, pues el resto no tienen cadenas de caracteres. Al menos eso es una buena noticia. En cuanto a las LUTS y demás... en principio no es buena idea almacenar cosas como variables globales en las librerías. Complicará la gestión de las dll sobre todo si en algún momento se hace algo multihilo, a no ser que estemos en las siguientes situaciones: 1.- cosas calculadas que sean estáticas y que se calculen cuando se cargue la dll y no vayan a sufrir variaciones (no dependan de parámetros de la imagen o del revelado). 2.- que se implemente una cache gestionada internamente. Por ejemplo si las LUT se calculan dinámicamente para una combinación de espacio de color y gamma dada, se puede almacenar la lut en una cache o Tabla con clave para buscarla y si existe no tener que calcularla. Las menos utilizadas se eliminarán automáticamente y las no existentes se crearían. Si luego se hacen llamadas reentrantes (multihilo) habrá que implementar un contador de uso para no eliminar una LUT que está siendo utilizada en otro hilo, pero eso no sería muy complicado, pues se implementaría en los algoritmos de acceso a los elementos cacheados. Última edición por ariznaf; 02-jun-2008 a las 23:06. |
|
||||
|
Cita:
Cita:
Cita:
.Cita:
__________________________________________________ ________ En otro orden de cosas, creo que nos estamos desviando de la idea original del proyecto. Estamos constantemente añadiendo nueva funcionalidad a la versión 1.0 y así no vamos a acabarla nunca. Todas estas cosas complican el proyecto una barbardidad y nos retrasan constantemente. No digo que no sean importantes, está claro que lo son, pero hace más de 15 días que teníamos el scroll/zoom funcionando, los chivatos y las vistas partidas, con que a eso le hubiésemos metido los controles ya sería suficiente de momento. No digo que estés tardando mucho, no me malinterpretes, fue culpa mía que en su momento, debí haber fusionado lo que teníamos y haber subido el resultado en paralelo a que tú lo siguieras mejorando. Tú estás haciéndolo fenomenal y al ritmo que puedas con tus otras obligaciones, ya sabes que prisa no tenemos. Lo que digo es que nos hemos puesto muy alto el listón de los que debe hacer la primera versión que liberemos. A estas alturas, yo ya podría tener todos los controles metidos (menos el WB por Temperatura de color) en el formulario y la salida a TIFF 16. Ya deberíamos tener un revelador funcional, aunque fuera con una sola vista sin testigos ni nada. Yo le veo más sentido a eso, a lanzar algo funcional cuanto antes y luego ir mejorándolo. Voy a intentar tener algo completo al final de esta semana y luego le vamos añadiendo las demás cosas que tenemos en desarrollo como si fueran mejoras... empiezo a ver que pierde fuelle el interés en el proyecto, como es lógico si no hacemos más que hablar y programar en casa y no subimos pruebas nuevas. Voy a abrir un nuevo tema que se llame versión 0.5 alpha 1, que hay que mantener el interés del proyecto en alto. Mi idea (que supongo que compartiréis) es sacar una versión funcional intermedia antes de la 1.0). Un saludo: Última edición por ManuelLlorens; 03-jun-2008 a las 15:22. |
|
|||
|
Manuel: he intentado hacer la prueba que dices del StringBuilder. Te cuento.
Efectivamente el problema creo que viene de ahí: al declararlo como string, antes no lo inicializábamos y por tanto no había memoria pedida para ello. Los objetos string son inmutables y no se puede escribir en ellos. En una versión antigua de PerfectRaw (que llamaba a GetInfo para obtener el modelo de cámara) he intentado hacer lo siguiente: Declarando los campos de IMAGE_INFO como StringBuilder, en dcraw.cs modifiqué GetInfo de la siguiente forma: Código:
publicvoid GetInfo()
{
info.timestamp = newStringBuilder(200);
info.camera_make = newStringBuilder(200);
info.camera_model = newStringBuilder(200);
info.artist = newStringBuilder(200);
info.filter_pattern = newStringBuilder(200);
DCRAW_GetInfo(ref info);
}
Código:
No se controló TypeLoadException: No se puede calcular la referencia del campo 'timestamp' del tipo 'IMAGE_INFO': El campo de clase o el campo de estructura no puede ser del tipo StringBuilder. Normalmente se puede conseguir el mismo efecto utilizando un campo String y realizando una inicialización previa de éste en una cadena con una longitud que coincida con la longitud del búfer apropiado. Intenté seguir el consejo que dan, declarando todo como string e inicializando en GetInfo las cadenas como sigue: Código:
publicvoid GetInfo()
{
info.timestamp = newstring(' ',200);
info.camera_make = newstring(' ', 200);
info.camera_model = newstring(' ', 200);
info.artist = newstring(' ', 200);
info.filter_pattern = newstring(' ', 200);
DCRAW_GetInfo(ref info);
}
Código:
No se controló una excepción del tipo AccessViolationException: Intento de leer o escribir en la memoria protegida. A menudo, esto indica que hay otra memoria dañada. Habrá que mirar un poco más el tema. De todas formas hay algo que no entiendo: Si en C se pide internamente memoria para las variables con malloc, esa memoria ¿quién la libera? Al pasar la estructura de vuelta, la máquina virtual debería de copiar las cadenas en un nuevo buffer de caracteres Unicode pidiendo memoria y luego liberar la anterior. Pero pobablemente eso no lo haga, pues no sabe si hemos pedido memoria con mallo o es memora estática. De ahí seguramente viene todo el lío. Quizás habría que redefinir la estructura en C con char definidos como campos de ancho fijo: char camera[200] en vez de como char* ¿no crees? Luego en C# habría que definirlo como una cadena de ancho fijo. Eso podría solucionar el problema ¿no crees? Cita:
A ver si la semana que viene (después de venir de Madrid) me vuelvo a meter con esto, pero he andado liado. Además como dije, me he enzafarrado con el tema de los zooms y varios cambios que se habían propuesto y ahora estoy en un punto que "ni pa trás ni palante": ni puedo recuperar las cosas tal cuál estaban cuando más o menos funcionaban y para seguir adelante tengo que implementar lo del zoom completo, integrándolo con lo de las transformaciones de dibujo de C# para poder dibujar las elipses de selección. Bueno es cuestión de dedicarle un par de días a fondo y lo tendré todo funcionando, pero mientras tanto... Esto me pasa por no ser previsor y guardar una versión funcional antes de meterme a seguir integrando cosas nuevas ![]() ![]() Pero bueno, veo que tú sigues para adelante y el programa tiene una buena funcionalidad, aunque el interface no sea el deseado. Tampoco es que haya puesto nueva funcionalidad al programa, es que al hacer cambios en lo de los zooms surgió de forma natural. El que sí que ha avanzado mucho en nuevas funciones eres tú, que he visto que tienes nuevos algoritmos para eliminación de laberintos y muchas otras cosas ![]() ¡¡Enhorabuena!!
__________________
Canon EOS 300D + Tamron SP AF 17-55mm f2.8 XR LD Aspherical (IF) + Canon EFS 60mm f2.8 Macro USM + Canon EF 70-200mm f/4 L USM+ Canon SpeedLite 420EX |
|
|||
|
Manuel:
He estado mirando el código de dcraw.dll y ¡¡No veo que se pida memoria para camera_make ni timestamp!! Quiero decir que en GetInfo directamente se asigna a info->camera_make desde la variable global make y lo mismo desde las otras varialbe, artist, etc. Si las funciones de reflexíón de C# andan copiando las cadenas y convirtíendolas a string unicode y luego LIBERAN la memoria, el problema puede estar ahí: se libera una memoria que está en el stack y no en la pila controlada por malloc. Para evitar esto, creo que lo mejor sería: o pedir un buffer con malloc en el que copiar los resultados (y que luego supuestamente liberaría la máquina virtual de C#) o bien declararlas como campos de longitud fija y suficiente char camera_make[200] y copiar las cadenas en ellas. La verdad es que no tengo muy claro el detalle de cómo hace C# para pasar una cadena entre C y C# y hacer las conversiones de ANSI a Unicode. He encontrado más información sobre el paso de strings en estructuras. Mira este enlace http://msdn.microsoft.com/en-us/library/e8w969hb.aspx ahí ponen varios ejemplos de distintos tipos de strings en estructuras (como char * como char[] etc) a ver si nos aclaramos de cuál es el adecuado.
__________________
Canon EOS 300D + Tamron SP AF 17-55mm f2.8 XR LD Aspherical (IF) + Canon EFS 60mm f2.8 Macro USM + Canon EF 70-200mm f/4 L USM+ Canon SpeedLite 420EX Última edición por ariznaf; 10-jun-2008 a las 20:22. |
|
||||
|
Tema StringBuilder
Donde tienes que poner el StringBuilder es en la definición de la struct en C#: Código:
[StructLayout(LayoutKind.Sequential)]
public struct IMAGE_INFO
{
public StringBuilder timestamp;
public StringBuilder camera_make;
public StringBuilder camera_model;
public StringBuilder artist;
public int iso_speed;
public float shutter;
public float aperture;
public float focal_length;
public float aspect_ratio;
public int raw_width;
public int raw_height;
public int in_width;
public int in_height;
public int out_width;
public int out_height;
public int raw_colors;
public StringBuilder filter_pattern;
}
__________________________________________ Cita:
Cita:
Lo de subir versiones con el interfaz semifuncional es por mantener el interés, pero estoy deseando ver tu interfaz terminado. Cita:
![]() ![]() Algún usuario de Oly se alegrá de que yo lo fuera, si no seguro que no me había puesto a tope con los laberintos. La verdad es que estoy contento porque el resultado es muy bueno.Un saludo: |
|
|||
|
Cita:
Aqui (http://support.microsoft.com/kb/321078) he encontrado más sobre el tema del Marshaling de strings en estructuras. Ahí dice explícitamente que en estructuras no se pueden usar stringbuilders y que ha de hacerse con strings Cita:
Por tanto el marshaling debería de ser de tipo UnmanagedType.ByValTStr especificando el tamaño de buffer maximo reservado (64 para artist, camera_make y camera_model y 26 para el timestamp devuelto por ctime, ya que según la ayuda ctime devuelve un puntero a un buffer stático de 26 caracteres). Código:
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
publicstructIMAGE_INFO
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst = 26)]
publicstring timestamp;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring camera_make;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring camera_model;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring artist;
publicint iso_speed;
publicfloat shutter;
publicfloat aperture;
publicfloat focal_length;
publicfloat aspect_ratio;
publicint raw_width;
publicint raw_height;
publicint in_width;
publicint in_height;
publicint out_width;
publicint out_height;
publicint raw_colors;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring filter_pattern;
}
En vez de leer Canon EOS leo €C. He probado usando charset.Ansi, auto y unicode y ninguno de elllos funciona bien. Según el mencionado artículo, debería de especificarse CharSet.Ansi en el StructLayout, pero no parece funcionar bien, o algo se me escapa (que es lo más seguro). También he probado a declarar en la estructura C camera_make como char camera_make[64] y hacer un strcpy(info->camera_make,make) para copiar la información de un lado a otro. El resultado es exactamente el mismo, no se la pega pero se siguen viendo los dos caracteres extraños que te comento en vez de el modelo de la cámara. A ver si tú consigues algo más.
__________________
Canon EOS 300D + Tamron SP AF 17-55mm f2.8 XR LD Aspherical (IF) + Canon EFS 60mm f2.8 Macro USM + Canon EF 70-200mm f/4 L USM+ Canon SpeedLite 420EX |
|
||||
|
Cita:
Un saludo: |
|
|||
|
Bueno, Manuel: ya tengo al menos una primera solución. El problema estaba con la forma en que se pasaban los punteros. Me explico: si en la estructura en C se declara una variable como char *, para pasárselo a C# en una estructura debería de ser un Unmanegtype.LPStr que es el correspondiente a un puntero a cadena ANSI terminada como null. Pero ese puntero, C# debe de entender que está en el HEAP y no en el stack (no sé si es que lo libera después de usarlo o qué hace con ello). El problema es que tu lo asignas a una variable global como make que no reside en el HEAP manejado por malloc. Una primera alternativa que he probado es declararlo en la estructura C como variables de caracter de tamaño fijo de la siguiente manera: Código:
typedef struct DCRAW_ImageInfo
{
char timestamp[26];
char camera_make[64];
char camera_model[64];
char artist[64];
int iso_speed;
float shutter;
float aperture;
float focal_length;
float aspect_ratio;
int raw_width;
int raw_height;
int in_width;
int in_height;
int out_width;
int out_height;
int raw_colors;
char filter_pattern[64];
}IMAGE_INFO;
Código:
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
publicstructIMAGE_INFO
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst = 26)]
publicstring timestamp;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring camera_make;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring camera_model;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring artist;
publicint iso_speed;
publicfloat shutter;
publicfloat aperture;
publicfloat focal_length;
publicfloat aspect_ratio;
publicint raw_width;
publicint raw_height;
publicint in_width;
publicint in_height;
publicint out_width;
publicint out_height;
publicint raw_colors;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
publicstring filter_pattern;
}
|