mirror of
https://github.com/eddyem/SBIG_340.git
synced 2025-12-06 02:35:12 +03:00
Add debayer via libraw
This commit is contained in:
parent
d123815433
commit
ae4b511542
47
Makefile
47
Makefile
@ -1,37 +1,46 @@
|
||||
# run `make DEF=...` to add extra defines
|
||||
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
|
||||
LDFLAGS += -lm -pthread
|
||||
LDIMG := $(shell pkg-config --libs libraw) -lgd $(shell pkg-config --libs cfitsio) -ltiff
|
||||
SRCS := $(wildcard *.c)
|
||||
#GCC_GE_4_9_3 := $(shell g++ -dumpversion | gawk '{print $$1>=4.9.3?"1":"0"}')
|
||||
DEFINES := $(DEF) -D_XOPEN_SOURCE=1111
|
||||
#ifeq ($(GCC_GE_4_9_3),1)
|
||||
DEFINES += -D_DEFAULT_SOURCE
|
||||
#else
|
||||
# DEFINES += -D_BSD_SOURCE
|
||||
#endif
|
||||
DEFINES := $(DEF) -D_GNU_SOURCE -D_XOPEN_SOURCE=1111
|
||||
#DEFINES += -DEBUG
|
||||
CFLAGS += -Wall -Wextra -O2 -std=gnu99
|
||||
CC = gcc
|
||||
CFLAGS += -Wall -Wextra -O2
|
||||
CFLAGS += $(shell pkg-config --cflags libraw)
|
||||
OBJS := $(SRCS:%.c=%.o)
|
||||
CC = gcc
|
||||
CPP = g++
|
||||
|
||||
all : sbig340 daemon client
|
||||
|
||||
sbig340 : $(SRCS)
|
||||
@echo -e "\t\tLD sbig340"
|
||||
$(CC) $(CFLAGS) $(DEFINES) $(LDFLAGS) $(shell pkg-config --libs cfitsio) -ltiff $(SRCS) -o sbig340
|
||||
debayer.o : debayer.cpp
|
||||
@echo -e "\t\tG++ debayer"
|
||||
$(CPP) $(CFLAGS) $(DEFINES) debayer.cpp -c
|
||||
|
||||
sbig340 : $(SRCS) debayer.o
|
||||
@echo -e "\t\tBuild sbig340"
|
||||
$(CC) -DDAEMON $(CFLAGS) -std=gnu99 $(DEFINES) $(LDFLAGS) $(LDIMG) $(SRCS) -o $@
|
||||
|
||||
# $(CC) -c $(CFLAGS) -std=gnu99 $(DEFINES) $(SRCS)
|
||||
# $(CPP) $(LDFLAGS) $(OBJS) debayer.o -o $@
|
||||
|
||||
daemon : $(SRCS)
|
||||
@echo -e "\t\tLD daemon"
|
||||
$(CC) -DDAEMON $(CFLAGS) $(DEFINES) $(LDFLAGS) $(SRCS) -o daemon
|
||||
@echo -e "\t\tBuild daemon"
|
||||
$(CC) -DDAEMON $(CFLAGS) -std=gnu99 $(DEFINES) $(LDFLAGS) $(SRCS) -o $@
|
||||
|
||||
client : $(SRCS)
|
||||
@echo -e "\t\tLD client"
|
||||
$(CC) -DCLIENT $(CFLAGS) $(DEFINES) $(LDFLAGS) $(shell pkg-config --libs cfitsio) -ltiff $(SRCS) -o client
|
||||
client : $(SRCS) debayer.o
|
||||
@echo -e "\t\tBuild client"
|
||||
$(CC) -DCLIENT $(CFLAGS) -std=gnu99 $(DEFINES) $(LDFLAGS) $(LDIMG) $(SRCS) debayer.o -o $@
|
||||
|
||||
clean:
|
||||
@echo -e "\t\tCLEAN"
|
||||
@rm -f $(OBJS) debayer.o
|
||||
|
||||
xclean: clean
|
||||
@echo -e "\t\tRM binaries"
|
||||
@rm -f sbig340 daemon client
|
||||
|
||||
gentags:
|
||||
CFLAGS="$(CFLAGS) $(DEFINES)" geany -g $(PROGRAM).c.tags *[hc] 2>/dev/null
|
||||
CFLAGS="$(CFLAGS) $(DEFINES)" geany -g $(PROGRAM).c.tags *[hc] *.cpp 2>/dev/null
|
||||
|
||||
.PHONY: gentags clean
|
||||
.PHONY: gentags clean xclean
|
||||
|
||||
107
debayer.cpp
Normal file
107
debayer.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* debayer.cpp - debayer image using libraw
|
||||
* based on openbayer_sample.cpp from LibRaw samples
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libraw/libraw.h>
|
||||
#include <gd.h>
|
||||
|
||||
#include "debayer.h"
|
||||
#include "usefull_macros.h"
|
||||
|
||||
static int write_jpeg(const char *fname, const uint8_t *data, imstorage *img){
|
||||
if(!img) return 1;
|
||||
size_t nx = img->W, ny = img->H;
|
||||
gdImagePtr im = gdImageCreateTrueColor(nx, ny);
|
||||
if(!im) return 4;
|
||||
//for(size_t y = 0; y < ny; ++y)for(size_t x = 0; x < nx; ++x) im->tpixels[y][x] = 0XFF0000;
|
||||
size_t x, y;
|
||||
for(y = 0; y < ny; ++y){
|
||||
for(x = 0; x < nx; ++x){
|
||||
im->tpixels[y][x] = (data[0] << 16) | (data[1] << 8) | data[2] ;
|
||||
data += 3;
|
||||
}
|
||||
}
|
||||
FILE *fp = fopen(fname, "w");
|
||||
if(!fp){
|
||||
fprintf(stderr, "Can't save jpg image %s\n", fname);
|
||||
gdImageDestroy(im);
|
||||
return 5;
|
||||
}
|
||||
char date[256];
|
||||
strftime(date, 256, "%d/%m/%y\n%H:%M:%S", localtime(&img->exposetime));
|
||||
gdFTUseFontConfig(1);
|
||||
char *ret = gdImageStringFT(im, NULL, 0xffffff, "monotype", 10, 0., 2, 12, date);
|
||||
if(ret) fprintf(stderr, "Error: %s\n", ret);
|
||||
im->tpixels[10][10] = 0XFF0000;
|
||||
im->tpixels[15][15] = 0XFF0000;
|
||||
gdImageJpeg(im, fp, 90);
|
||||
fclose(fp);
|
||||
gdImageDestroy(im);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debayer image `img` and store it
|
||||
* @param black - black level (minimum on image)
|
||||
* @return 0 if all OK
|
||||
*/
|
||||
int write_debayer(imstorage *img, uint16_t black){
|
||||
char *name = make_filename(img, SUFFIX_JPEG);
|
||||
if(!name) return 1;
|
||||
int r = 0;
|
||||
size_t fsz = img->W * img->H * sizeof(uint16_t);
|
||||
LibRaw rp;
|
||||
rp.imgdata.params.output_tiff = 1;
|
||||
int ret = rp.open_bayer((unsigned char*)img->imdata, fsz, img->W, img->H,
|
||||
0,0,0,0,0, LIBRAW_OPENBAYER_BGGR, 0,0, black);
|
||||
if(ret != LIBRAW_SUCCESS) return 2;
|
||||
if ((ret = rp.unpack()) != LIBRAW_SUCCESS){
|
||||
WARNX(_("Unpack error: %d"), ret);
|
||||
rp.recycle();
|
||||
return 3;
|
||||
}
|
||||
if((ret = rp.dcraw_process()) != LIBRAW_SUCCESS){
|
||||
WARNX(_("Processing error: %d"), ret);
|
||||
rp.recycle();
|
||||
return 4;
|
||||
}
|
||||
libraw_processed_image_t *image = rp.dcraw_make_mem_image(&ret);
|
||||
if(!image){
|
||||
WARNX(_("Can't make memory image: %d"), ret);
|
||||
rp.recycle();
|
||||
return 5;
|
||||
}
|
||||
if(image->type != LIBRAW_IMAGE_BITMAP){
|
||||
r = 6; goto retn;
|
||||
}
|
||||
if(image->colors != 3){
|
||||
r = 7; goto retn;
|
||||
}
|
||||
write_jpeg(name, image->data, img);
|
||||
retn:
|
||||
LibRaw::dcraw_clear_mem(image);
|
||||
rp.recycle();
|
||||
return r;
|
||||
}
|
||||
38
debayer.h
Normal file
38
debayer.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* geany_encoding=koi8-r
|
||||
* debayer.h
|
||||
*
|
||||
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __DEBAYER_H__
|
||||
#define __DEBAYER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "imfunctions.h"
|
||||
int write_debayer(imstorage *img, uint16_t black);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // __DEBAYER_H__
|
||||
@ -28,6 +28,7 @@
|
||||
#include <math.h> // sqrt
|
||||
#include <time.h> // time, gmtime etc
|
||||
#ifndef DAEMON
|
||||
#include "debayer.h"
|
||||
#include <fitsio.h> // save fits
|
||||
#include <tiffio.h> // save tiff
|
||||
#endif
|
||||
@ -51,20 +52,16 @@ void modifytimestamp(char *filename, imstorage *img){
|
||||
if(utimensat(AT_FDCWD, filename, times, 0)) WARN(_("Can't change timestamp for %s"), filename);
|
||||
}
|
||||
|
||||
// image type suffixes
|
||||
#define SUFFIX_FITS "fits"
|
||||
#define SUFFIX_RAW "bin"
|
||||
#define SUFFIX_TIFF "tiff"
|
||||
|
||||
/**
|
||||
* NON THREAD-SAFE!
|
||||
* make filename for given name, suffix and storage type
|
||||
* @return filename or NULL if can't create it
|
||||
*/
|
||||
static char *make_filename(imstorage *img, const char *suff){
|
||||
char *make_filename(imstorage *img, const char *suff){
|
||||
struct stat filestat;
|
||||
static char buff[FILENAME_MAX];
|
||||
store_type st = img->st;
|
||||
DBG("Make filename from %s with suffix %s", img->imname, suff);
|
||||
char fnbuf[FILENAME_MAX], *outfile = img->imname;
|
||||
if(img->timestamp){
|
||||
struct tm *stm = localtime(&img->exposetime);
|
||||
@ -107,6 +104,7 @@ static char *make_filename(imstorage *img, const char *suff){
|
||||
* Check image to store
|
||||
* @param filename (i) - output file name (or prefix with suffix)
|
||||
* @param store (i) - "overwrite" (or "rewrite"), "normal" (or NULL), "enumerate" (or "numerate")
|
||||
* @param format (i) - image format (ft[rd])
|
||||
*/
|
||||
imstorage *chk_storeimg(char *filename, char* store, char *format){
|
||||
FNAME();
|
||||
@ -124,6 +122,7 @@ imstorage *chk_storeimg(char *filename, char* store, char *format){
|
||||
char *nm = strdup(filename);
|
||||
if(!nm) ERRX("strdup");
|
||||
char *pt = strrchr(nm, '.');
|
||||
DBG("input format: %s", format);
|
||||
image_format fbysuff = FORMAT_NONE;
|
||||
// check if name's suffix is filetype
|
||||
if(pt){
|
||||
@ -151,7 +150,7 @@ imstorage *chk_storeimg(char *filename, char* store, char *format){
|
||||
if(fbysuff != FORMAT_NONE) fmt = fbysuff;
|
||||
DBG("fmt: %d", fmt);
|
||||
}
|
||||
|
||||
DBG("imformat: %d", fmt);
|
||||
// now check all names
|
||||
#define FMTSZ (3)
|
||||
image_format formats[FMTSZ] = {FORMAT_FITS, FORMAT_TIFF, FORMAT_RAW};
|
||||
@ -278,6 +277,7 @@ int writefits(imstorage *img){
|
||||
char buf[80];
|
||||
fitsfile *fp;
|
||||
char *filename = make_filename(img, SUFFIX_FITS);
|
||||
if(!filename) return 1;
|
||||
TRYFITS(fits_create_file, &fp, filename);
|
||||
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
|
||||
// FILE / Input file original name
|
||||
@ -405,9 +405,9 @@ int save_histo(FILE *f, imstorage *img){
|
||||
printf("low 2%% (%zd pixels) = %d, median (%zd pixels) = %d, up 2%% (%zd pixels) = %d\n",
|
||||
low2, lval, med, mval, up2, tval);
|
||||
double mul = 1., mulmax = 255. / tval;
|
||||
if(tval <= 252){ // no overexposed pixels
|
||||
if(tval <= 240){ // no overexposed pixels
|
||||
if(lval < 32){ // narrow histogram with overexposed black level
|
||||
mul = 252. / tval;
|
||||
mul = 240. / tval;
|
||||
}else mul = 32. / lval;
|
||||
}else{
|
||||
if(mval > 134){
|
||||
@ -418,7 +418,7 @@ int save_histo(FILE *f, imstorage *img){
|
||||
if(mul > mulmax) mul = mulmax;
|
||||
double E = img->exptime * mul;
|
||||
if(E < 5e-5) E = 5e-5; // too short exposition
|
||||
else if(E > 120.) E = 120.; // no need to do expositions larger than 2 minutes
|
||||
else if(E > 300.) E = 300.; // no need to do expositions larger than 5 minutes
|
||||
green("Recommended exposition time: %g seconds\n", E);
|
||||
exp_calculated = E;
|
||||
return 0;
|
||||
@ -477,12 +477,13 @@ int store_image(imstorage *img){
|
||||
if(img->imformat & FORMAT_TIFF){ // save tiff file
|
||||
if(writetiff(img)) status |= 1;
|
||||
}
|
||||
if(img->imformat & FORMAT_RAW){
|
||||
if(img->imformat & FORMAT_RAW){ // save RAW dump & truncated histogram
|
||||
if(writedump(img)) status |= 2;
|
||||
}
|
||||
if(img->imformat & FORMAT_FITS){ // not supported yet
|
||||
if(img->imformat & FORMAT_FITS){ // save FITS
|
||||
if(writefits(img)) status |= 4;
|
||||
}
|
||||
if(write_debayer(img, glob_min)) status |= 8; // and save colour image
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -72,6 +72,13 @@ typedef struct{
|
||||
|
||||
extern double exp_calculated;
|
||||
|
||||
// image type suffixes
|
||||
#define SUFFIX_FITS "fits.gz"
|
||||
#define SUFFIX_RAW "bin"
|
||||
#define SUFFIX_TIFF "tiff"
|
||||
#define SUFFIX_JPEG "jpg"
|
||||
|
||||
char *make_filename(imstorage *img, const char *suff);
|
||||
imstorage *chk_storeimg(char *filename, char* store, char *format);
|
||||
int store_image(imstorage *filename);
|
||||
void print_stat(imstorage *img);
|
||||
|
||||
1
main.c
1
main.c
@ -80,6 +80,7 @@ int main(int argc, char **argv){
|
||||
#endif // !CLIENT
|
||||
#ifndef DAEMON
|
||||
img = chk_storeimg(G->outpfname, G->imstoretype, G->imformat);
|
||||
if(!img) return 1;
|
||||
#else
|
||||
img = MALLOC(imstorage, 1); // just allocate empty: all we need in daemon is exposition & binning
|
||||
#endif
|
||||
|
||||
@ -333,7 +333,7 @@ size_t read_tty(uint8_t *buff, size_t length){
|
||||
int retval;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(comfd, &rfds);
|
||||
tv.tv_sec = 0; tv.tv_usec = 500000; // wait for 500ms max
|
||||
tv.tv_sec = 0; tv.tv_usec = 500000; // wait for 500ms
|
||||
retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
|
||||
if (!retval) return 0;
|
||||
if(FD_ISSET(comfd, &rfds)){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user