AlSvartr

Libraries/routines C++ pour la lecture de sequences .ser?

Recommended Posts

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

Edited by AlSvartr

Share this post


Link to post
Share on other sites
Advertising
By registering on Astrosurf,
this type of ad will no longer be displayed.
Planetary Astronomy
Observing, imaging and studying the planets
A comprehensive book about observing, imaging, and studying planets. It has been written by seven authors, all being skillful amateur observers in their respective domains.
More information on www.planetary-astronomy.com

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

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Hello Marc,

 

Un tout grand merci pour le partage de ton code!! Je vais voir comment adapter ça sous Linux.

 

a+
 

Simon

 

 

Share this post


Link to post
Share on other sites

@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".

Edited by AlSvartr

Share this post


Link to post
Share on other sites

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

 

Share this post


Link to post
Share on other sites

@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.

Edited by AlSvartr

Share this post


Link to post
Share on other sites

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

  • Thanks 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now