1 #ifndef _SER_H_
2 #define _SER_H_
3 
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7 
8 #include <stdio.h>
9 #ifdef _OPENMP
10 #include <omp.h>
11 #endif
12 #include "core/siril.h"
13 #include "io/seqwriter.h"
14 
15 /* This file is part of Siril, https://free-astro.org/
16  *
17  * WARNING: the code in this file and its .c counterpart will not work properly
18  * on big endian systems.
19  */
20 
21 #if defined(__unix__) || (defined(OS_OSX))
22 #include <sys/param.h>		// define or not BSD macro
23 #endif
24 
25 #ifdef __linux__
26 #define fseek64 fseeko  // Linux
27 #define ftell64 ftello  // Linux
28 #elif defined (OS_OSX)
29 #define fseek64 fseeko  // OS X
30 #define ftell64 ftello  // OS X
31 #elif defined(BSD)
32 #define fseek64 fseeko  // DragonFly BSD, FreeBSD, OpenBSD, NetBSD
33 #define ftell64 ftello  // DragonFly BSD, FreeBSD, OpenBSD, NetBSD
34 #elif defined (__FreeBSD_kernel__) && defined (__GLIBC__)
35 #define fseek64 fseeko  // kFreeBSD
36 #define ftell64 ftello  // kFreeBSD
37 #elif defined (__gnu_hurd__)
38 #define fseek64 fseeko  // GNU/Hurd
39 #define ftell64 ftello  // GNU/Hurd
40 #elif defined(__CYGWIN__)
41 #define fseek64 fseeko  // CYGWIN
42 #define ftell64 ftello  // CYGWIN
43 #else
44 #define fseek64 _fseeki64  // Windows
45 #define ftell64 _ftelli64  // Windows
46 #endif
47 
48 
49 #define SER_HEADER_LEN 178
50 
51 typedef enum {
52 	SER_MONO = 0,
53 	SER_BAYER_RGGB = 8,
54 	SER_BAYER_GRBG = 9,
55 	SER_BAYER_GBRG = 10,
56 	SER_BAYER_BGGR = 11,
57 	SER_BAYER_CYYM = 16,
58 	SER_BAYER_YCMY = 17,
59 	SER_BAYER_YMCY = 18,
60 	SER_BAYER_MYYC = 19,
61 	SER_RGB = 100,	// SER v3
62 	SER_BGR = 101	// SER v3
63 } ser_color;
64 
65 /* Endianness of the frame data for 16-bit images */
66 typedef enum {
67 //	SER_BIG_ENDIAN = 0 /* = FALSE */, SER_LITTLE_ENDIAN = 1 /* = TRUE */
68 	/* For an unknown reason, several of the first programs to support SER
69 	 * disrespect the specification regarding the endianness flag. The specification
70 	 * states that a boolean value is used for the LittleEndian header, and they
71 	 * use it as a BigEndian header, with 0 for little-endian and 1 for big-endian.
72 	 * Consequently, to not break compatibility with these first implementations,
73 	 * later programs, like Siril and GoQat, have also decided to implement this
74 	 * header in opposite meaning to the specification. */
75 	SER_LITTLE_ENDIAN = 0, SER_BIG_ENDIAN = 1
76 } ser_endian;
77 
78 typedef enum {
79 	SER_PIXEL_DEPTH_8 = 1, SER_PIXEL_DEPTH_16 = 2
80 } ser_pixdepth;
81 
82 
83 /* this struct does not reflect the exact header:
84  * - strings are nul-terminated, which makes them one character larger than in
85  *   the header
86  * - the integer types of the header are little endian, which may not be the
87  *   case when compiling the struct
88  */
89 struct ser_struct {
90 	char *file_id;			// 14 bytes (0)
91 	int lu_id;			// 4	(14)
92 	ser_color color_id;		// 4	(18)
93 	ser_endian little_endian;	// 4	(22)
94 	int image_width;		// 4	(26)
95 	int image_height;		// 4	(30)
96 	int bit_pixel_depth;		// 4	(34)
97 	unsigned int frame_count;	// 4	(38)
98 	char observer[40];		// 40	(42)
99 	char instrument[40];		// 40	(82)
100 	char telescope[40];		// 40	(122)
101 	guint64 date;		// 8	(162)
102 	guint64 date_utc;	// 8 (170)
103 
104 	/* timestamps (not in the header, timestamps are in trailer) */
105 	guint64 *ts;			// total timestamps
106 	int ts_alloc;			// allocated number of elements in ts
107 	guint64 ts_min, ts_max;// min and max timestamp
108 	double fps;				// frame rate
109 
110 	gint64 filesize;			// size of the file
111 
112 	// internal representations of header data
113 	ser_pixdepth byte_pixel_depth;	// more useful representation of the bit_pixel_depth
114 	unsigned int number_of_planes;	// derived from the color_id
115 	FILE *file;
116 	char *filename;
117 #ifdef _OPENMP
118 	omp_lock_t fd_lock, ts_lock;
119 #endif
120 
121 	struct seqwriter_data *writer;
122 };
123 
124 gboolean ser_is_cfa(struct ser_struct *ser_file);
125 void ser_convertTimeStamp(struct ser_struct *ser_file, GSList *timestamp);
126 void ser_init_struct(struct ser_struct *ser_file);
127 void ser_display_info(struct ser_struct *ser_file);
128 int ser_open_file(const char *filename, struct ser_struct *ser_file);
129 int ser_close_and_delete_file(struct ser_struct *ser_file);
130 int ser_write_and_close(struct ser_struct *ser_file);
131 int ser_create_file(const char *filename, struct ser_struct *ser_file, gboolean overwrite, struct ser_struct *copy_from);
132 int ser_close_file(struct ser_struct *ser_file);
133 int ser_metadata_as_fits(struct ser_struct *ser_file, fits *fit);
134 int ser_read_frame(struct ser_struct *ser_file, int frame_no, fits *fit, gboolean force_float, gboolean open_debayer);
135 int ser_read_opened_partial_fits(struct ser_struct *ser_file, int layer,
136 		int frame_no, fits *fit, const rectangle *area);
137 int ser_read_opened_partial(struct ser_struct *ser_file, int layer,
138 		int frame_no, WORD *buffer, const rectangle *area);
139 int ser_write_frame_from_fit(struct ser_struct *ser_file, fits *fit, int frame);
140 gint64 ser_compute_file_size(struct ser_struct *ser_file, int nb_frames);
141 int import_metadata_from_serfile(struct ser_struct *ser_file, fits *to);
142 GdkPixbuf* get_thumbnail_from_ser(char *filename, gchar **descr);
143 GDateTime *ser_read_frame_date(struct ser_struct *ser_file, int frame_no);
144 
145 #endif
146 
147