AlSvartr 2 870 Posté(e) 21 février 2021 (modifié) Hello, Je cherche à savoir si il y a quelque part des routines C++ en accès public permettant de lire les sequences .ser (+ metadonnées). Voire, si la lecture est faisable via des librairies standards, les instructions d'utilisation. Je suis preneur de toute info Bon dimanche, Simon Modifié 21 février 2021 par AlSvartr Partager ce message Lien à poster Partager sur d’autres sites
patry 1 963 Posté(e) 21 février 2021 Voilà ce que j'avais écrit il y a des années pour corriger certains SER dont les paramètres étaient mal enregistrés. Une fois la structure renseignée, il est assez basique de lire les données. Par contre l'analyse est plus complexe. Dans mon cas, il faut analyser la taille du fichier (à priori correcte), lui enlever l'entête, et diviser par la taille image (X, Y, bpp, forcément renseignée au début de la capture), pour savoir s'il y a un horodatage ou pas, puis corriger selon le cas le nombre de vues (forcément renseigné en fin de capture), quitte à virer l'horodatage au besoin. Là c'est du code "à façon" qui n'est pas reproductible. J'ai malheureusement perdu mon application et il ne me reste que quelques bribes de code dont cette partie (visual studio 6 je crois) : typedef __int8 int8__t; typedef unsigned __int8 uint8__t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #define SER_signature "LUCAM-RECORDER" #define MONO 0 #define BAYER_RGGB 8 #define BAYER_GRBG 9 #define BAYER_GBRG 10 #define BAYER_BGGR 11 #define BAYER_CYYM 16 #define BAYER_YCMY 17 #define BAYER_YMCY 18 #define BAYER_MYYC 19 extern const char* COLID_TABLE[20]; extern const char* ENDIAN_TABLE[2]; #define K_IN_SEC 10000000 #define SER_big_endian 0 #define SER_little_endian 1 #pragma pack (push) #pragma pack (1) typedef struct { char FileID[14]; uint32_t LuID; uint32_t ColorID; uint32_t Endian; uint32_t ImageWidth; uint32_t ImageHeight; uint32_t PixelDepth; uint32_t FrameCount; char Observer[40]; char Instrument[40]; char Telescope[40]; int64_t DateTime; int64_t DateTime_UTC; } T_SER_header; #pragma pack (pop) ... Le truc le plus important, lecture et analyse du header pour lever certains discrets ... /** * \brief Open ser file * Open a new SER file and read header in memory. When available, frame datation is * also read and maintained in ram. * File is open in R/W mode for binary access, and all accesses are done in 64 bit mode. * * \param filename to open * \return boolean set to true when openning file is ok */ bool SEReditor::openSER(System::String^ filename) { errno_t error; int64_t TZinSEC; msclr::interop::marshal_context cxt; // first, remove unused memory if any if (frdate_p != NULL) { free( frdate_p ); frdate_p = NULL; } if (fd_ser != -1) { _close(fd_ser); fd_ser = -1; } // open file error = _sopen_s(&fd_ser, convertSystemString2char(filename), O_RDWR | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE); if (error != 0) { System::Windows::Forms::MessageBox::Show("File do not open", "Error", MessageBoxButtons::OK); // MessageBox::Show("Open file "+filename+" error", "Exit", MessageBoxButtons::OK, MessageBoxIcon::Error); return (false); } // go to the end of the file to get it's size filesz = _lseeki64(fd_ser, 0LL, SEEK_END); if (this->filesz < sizeof(T_SER_header)) { System::Windows::Forms::MessageBox::Show("No SER header found. Aborting", "Error", MessageBoxButtons::OK); return(false); } // go back to the beginning of the file _lseeki64(fd_ser, 0LL, SEEK_SET); _read(fd_ser, &SER_header_s, sizeof(T_SER_header)); if ((SER_header_s.ImageWidth>4096) || (SER_header_s.ImageHeight>4096) || (SER_header_s.PixelDepth>16)) { System::Windows::Forms::MessageBox::Show("Bad SER header. Aborting", "Error", MessageBoxButtons::OK); return(false); } // copy all strings contents strncpy_s(bufferObserver, 41, SER_header_s.Observer, 40); strncpy_s(bufferInstrument, 41, SER_header_s.Instrument, 40); strncpy_s(bufferTelescope, 41, SER_header_s.Telescope, 40); // Compute TimeZone from header contents. TZ = SER_header_s.DateTime-SER_header_s.DateTime_UTC; TZinSEC = TZ / K_IN_SEC; if ((TZinSEC*TZinSEC) > 1866240000) { // problem with TZ, is greater than 12 hours (say 12*3600 sec) in absolute value TZ = 0; } // Compute frame datation relative position // position is framecount * width * height * pixel_depth (1 or 2 bytes) + SER header size offsetDatation = SER_header_s.ImageWidth * SER_header_s.ImageHeight; offsetDatation *= SER_header_s.FrameCount; if (SER_header_s.PixelDepth >8) offsetDatation *= 2; offsetDatation += sizeof(T_SER_header); // Compute size of frame datation section // size = framecount * int64 sizeDatation = SER_header_s.FrameCount * sizeof(uint64_t); // file contain datation ? if ((offsetDatation + sizeDatation) > filesz) { frameDatationPresent = false; // No frame datation in file // by default, we are unable to check date's validity // So all are assumed to be ok, frameDatationUTC = true; headerDatationOK = true; } else { // set flag frameDatationPresent frameDatationPresent = true; // allocate's frame datation area frdate_p = (int64_t*) calloc(sizeDatation, 1); // go to begining of frames datation and read the block _lseeki64(fd_ser, offsetDatation, SEEK_SET); _read(fd_ser, &frdate_p[0], sizeDatation); } return(true); } Le problème est que j'ai fait ça avec un visual (je ne suis pas un programmeur windows non plus) qui n'est plus supporté et dont certaines spécificités ne permettent pas un portage facile sur une nouvelle version. Aujourd'hui je pourrais reporter le tout sur une version sans IHM sous Linux (ou WSL). La portabilité de l'IHM est médiocre donc ne sera pas reprise. Marc 1 Partager ce message Lien à poster Partager sur d’autres sites
AlSvartr 2 870 Posté(e) 21 février 2021 Hello Marc, Un tout grand merci pour le partage de ton code!! Je vais voir comment adapter ça sous Linux. a+ Simon Partager ce message Lien à poster Partager sur d’autres sites
Oodini 247 Posté(e) 21 février 2021 Ça pourrait t'aider : https://github.com/cgarry/ser-player 1 Partager ce message Lien à poster Partager sur d’autres sites
AlSvartr 2 870 Posté(e) 21 février 2021 (modifié) @Oodini Oui en effet je suis tombé sur ces codes en fouillant sur le web. La petite complication c'est qu'il y a pas mal de dépendances à des classes pas forcément utiles qui vont demander un sacré boulot de "nettoyage". Modifié 21 février 2021 par AlSvartr Partager ce message Lien à poster Partager sur d’autres sites
patry 1 963 Posté(e) 22 février 2021 C'est pour cela qu'il te faut déterminer ton besoin, et construire les classes dont tu a besoin. Et surtout n'y mettre QUE ce qui est nécessaire à la classe (les accesseurs et quelques méthodes qui lui sont propres). Besoin de plus => faire une autre classe, éventuellement "friend" si vraiment cela s'avère nécessaire ! Cela limite grandement les interdépendances et au final les classes sont vachement plus portables. Ce qui existe ailleurs ... bin si la proposition du dessus n'est pas remplie, c'est que finalement c'est mal foutu et tu ne pourra que t'en inspirer ! Maintenant pour faire un truc pour toi, sur un coin de table, c'est sur que tu n'est pas obligé de te mettre ses contraintes ! Marc Partager ce message Lien à poster Partager sur d’autres sites
AlSvartr 2 870 Posté(e) 22 février 2021 (modifié) @patry Oh moi je sais parfaitement ce dont j'ai besoin. Mon problème réside dans la compréhension et extraction des codes strictement nécessaires à la lecture des .ser. En fait ça aurait été super que les auteurs du format fournissent une petite API ou librairie. Modifié 22 février 2021 par AlSvartr Partager ce message Lien à poster Partager sur d’autres sites
chonum 976 Posté(e) 22 février 2021 J'ai la version c#, pas trop dur à transcrire en C++ Je mets le source de la partie visualisation de la SER toolbox de Genika. Visu.cs 1 Partager ce message Lien à poster Partager sur d’autres sites
AlSvartr 2 870 Posté(e) 22 février 2021 Merci Fred! Partager ce message Lien à poster Partager sur d’autres sites