Commit aaf21f58 authored by Filip Hroch's avatar Filip Hroch

New upstream version 1.4

parent bc7f4f37
This diff is collapsed.
......@@ -2,7 +2,7 @@
SUBDIRS = images
bin_PROGRAMS = fitspng
fitspng_SOURCES = qmed.c main.c fitspng.c
fitspng_SOURCES = cielab.c tone.c ecdf.c fitspng.c main.c
fitspng_LDADD = -lm
man_MANS = fitspng.1
......
......@@ -103,7 +103,8 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
"$(DESTDIR)$(htmldir)"
PROGRAMS = $(bin_PROGRAMS)
am_fitspng_OBJECTS = qmed.$(OBJEXT) main.$(OBJEXT) fitspng.$(OBJEXT)
am_fitspng_OBJECTS = cielab.$(OBJEXT) tone.$(OBJEXT) ecdf.$(OBJEXT) \
fitspng.$(OBJEXT) main.$(OBJEXT)
fitspng_OBJECTS = $(am_fitspng_OBJECTS)
fitspng_DEPENDENCIES =
AM_V_P = $(am__v_P_@AM_V@)
......@@ -342,7 +343,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = images
fitspng_SOURCES = qmed.c main.c fitspng.c
fitspng_SOURCES = cielab.c tone.c ecdf.c fitspng.c main.c
fitspng_LDADD = -lm
man_MANS = fitspng.1
dist_html_DATA = README fitspng.html
......@@ -436,9 +437,11 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cielab.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fitspng.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qmed.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tone.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
......
FITS to PNG convertor
FITSPNG
is an utility intended to convert of images in astronomical
FITS to PNG format.
Homepage:
http://integral.physics.muni.cz/fitspng/
Sources:
http://integral.physics.muni.cz/hg/fitspng/
INSTALLATION
General:
$ autoreconf -i
$ autoreconf -i # sources by Hg
$ ./configure
$ make
$ su
......@@ -29,10 +34,9 @@ INSTALLATION
Fedora
[ place to ~/rpmbuid/SOURCES, extract .spec to ~/rpmbuid/SPEC
$ cd ~/rpmbuid/SPEC
$ rpmbuild fitspng.spec
$ su
$ rpm -i ~/rpmbuid/RPMS/fitspng_*.rpm
\ No newline at end of file
/*
CIELAB implementation for FITSPNG FITS to PNG converter
Copyright (C) 2018 Filip Hroch, Masaryk University, Brno, CZ
Fitspng 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 3 of the License, or
(at your option) any later version.
Fitspng 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 Fitspng. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fitspng.h"
#include <math.h>
#include <assert.h>
// https://en.wikipedia.org/wiki/CIELAB_color_space
/* CIE Lab, D65 white point */
const float Xn = 95.047;
const float Yn = 100.0;
const float Zn = 108.883;
/* CIE Lab parameters */
const float d = 6.0 / 29.0;
const float a = 0.2068965; /* = 3 * (6/29)**2 */
const float b = 4.0 / 29.0;
float Lab_fun(float I, float In)
{
const float d3 = d*d*d;
float r;
r = I / In;
return r > d3 ? cbrtf(r) : r / a + b;
}
float Lab_invfun(float f, float In)
{
return In * (f > d ? f*f*f : a*(f - b));
}
void XYZ_Lab(float X, float Y, float Z, float *L, float *a, float *b)
{
float fx, fy, fz;
fx = Lab_fun(X,Xn);
fy = Lab_fun(Y,Yn);
fz = Lab_fun(Z,Zn);
*L = 116.0f*fy - 16.0f;
*a = 500.0f*(fx - fy);
*b = 200.0f*(fy - fz);
}
void Lab_XYZ(float L, float a, float b, float *X, float *Y, float *Z)
{
float Lx, ax, bx;
Lx = (L + 16.0f) / 116.0f;
ax = Lx + a / 500.0f;
bx = Lx - b / 200.0f;
*X = Lab_invfun(ax,Xn);
*Y = Lab_invfun(Lx,Yn);
*Z = Lab_invfun(bx,Zn);
}
This diff is collapsed.
AC_PREREQ([2.69])
AC_INIT([fitspng],[1.3],[hroch@physics.muni.cz])
AC_INIT([fitspng],[1.4],[hroch@physics.muni.cz])
AM_INIT_AUTOMAKE
AC_PROG_CC
AC_PROG_INSTALL
AC_C_BIGENDIAN
AC_C_INLINE
AC_FUNC_MALLOC
AC_CHECK_HEADERS([stdlib.h string.h])
AC_CHECK_HEADERS([math.h])
AC_CHECK_LIB([m], [powf])
dnl check for FITSIO library
dnl FITSIO library
AC_CHECK_HEADERS([fitsio.h])
AC_CHECK_LIB([cfitsio],[ffclos],[],[
AC_CHECK_LIB([cfitsio],[ffopen],[],[
echo "configure: no cfitsio library found"
echo
echo "Please check installation of cfitsio and try again."
......@@ -22,7 +22,7 @@ AC_CHECK_LIB([cfitsio],[ffclos],[],[
exit 1],
[-lm])
dnl check for PNG library
dnl PNG library
AC_CHECK_HEADERS([png.h])
AC_CHECK_LIB([png],[png_init_io],[],[
echo "configure: no png library found"
......
/*
FITSPNG -- empirical distribution function
Copyright (C) 2019 Filip Hroch, Masaryk University, Brno, CZ
Fitspng 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 3 of the License, or
(at your option) any later version.
Fitspng 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 Fitspng. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fitspng.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
#include <assert.h>
#define EPSILON 2*FLT_EPSILON
#define CMP(x,y) ((x) < (y) ? -1 : ((x) > (y) ? 1 : 0))
static int fcmp(const void *u, const void *v)
{
return CMP(*(const float *) u, *(const float *) v);
/*
const float x = *(const float *) u;
const float y = *(const float *) v;
if( x < y )
return -1;
else if( x > y )
return 1;
else
return 0;
*/
}
/* alternative with modified data */
int ecdf(long n, const float *data, float *xcdf, float *ycdf)
{
assert(n > 0 && data);
long m = n * sizeof(float);
float *d;
if( (d = malloc(m)) == NULL )
perror("There is no room for data sort in CDF.");
memcpy(d,data,m);
qsort(d,n,sizeof(float),fcmp);
/* remove duplicities */
m = 1;
for(long i = 1; i < n; i++) {
if( fabsf(d[i] - d[m]) > EPSILON )
d[m++] = d[i];
}
/* setup CDF */
memcpy(xcdf,d,m*sizeof(float));
float h = 1.0 / (float)(m + 1);
for(long i = 0; i < m; i++) ycdf[i] = i*h;
free(d);
return m;
}
float quantile(long ncdf, const float *xcdf, const float *ycdf, float q)
{
long n = ncdf;
if( n == 0 )
return 0.0;
else if( n == 1 )
return xcdf[0];
if( q < ycdf[0] )
return xcdf[0];
else if( q > ycdf[n-1] )
return(xcdf[n-1]);
else {
float h = 1.0 / (float)(n + 1);
float r = q / h;
int m = roundf(r);
if( fabsf(m - r) < EPSILON )
return(xcdf[m]);
else {
int low = r;
int high = low + 1;
float dy = ycdf[high] - ycdf[low];
if( fabsf(dy) > EPSILON )
// inverse by linear interpolation
return((xcdf[high] - xcdf[low])/dy*(q - ycdf[low]) + xcdf[low]);
else {
// nearly singular
return((xcdf[high] + xcdf[low]) / 2);
}
}
}
}
.TH FITSPNG 1 "May 2011" "Munipack project" "User Commands"
.TH FITSPNG 1 "January 2019" "Fitspng" "User Commands"
.SH NAME
fitspng \- FITS to PNG converter.
.SH SYNOPSIS
.B fitspng
.I [options] file
.I [options] file(s)
.SH DESCRIPTION
Fitspng is an utility intended to convert of images in astronomical FITS
format to computer graphics PNG format.
......@@ -53,16 +53,21 @@ only for colour FITS.
Select the colour-space of output image.
.TP
.B \-s s
Scale down the size of image by the specified factor s as a (non-zero) positive
integer number. If the s factor is greater of one, any output pixel
is constructed as the arithmetical mean of s*s input pixels.
Shrink image: scale down the size of image by the specified factor s as
a (non-zero) positive integer number. If the s factor is greater of one,
any output pixel is constructed as arithmetic mean of s*s input pixels.
.TP
.B \-o
Output image name. Default value is fitspng.png.
Specify an output file name, valid only if a single file is passed.
If this switch is omitted, the output filename is determined by
modification of input filenames: suffixes, like *.fits, are replaced by *.png,
and the directory path is removed. The approach leaves original data untouched,
results are stored in current working directory.
.TP
.B \-B [8|16]
8 bites per pixel of colour (grey) depth of output. This is default.
16 bites per pixel of colour (grey) depth of output. There is frequently
8 bites per pixel of colour (gray) depth of output. This is default.
16 bites per pixel of colour (gray) depth of output. There is frequently
problem with additional rendering. Most of utilities doesn't work with this
colour depth correctly. On the other side, 16 bit per pixel images
has saved photometric content more precisely.
......@@ -77,23 +82,23 @@ Show summary of options.
Display software version.
.SH EXAMPLES
Convert an image from FITS to PNG:
$ fitspng grey.fits \-o grey.png
$ fitspng \-o gray.png gray.fits
.PP
Emulate human's night vision:
$ fitspng colour.fits \-o colour.png \-fn 100,10
$ fitspng \-fn 100,10 \-o scotopic.png colour.fits
.PP
Emulate classical photography sensitivity function (density curve):
$ fitspng colour.fits \-o colour.png \-f logistic
$ fitspng \-f logistic \-o photo.png colour.fits
.PP
Create semi-grey image:
$ fitspng colour.fits \-o colour.png \-fs 0.2
Create semi-gray image:
$ fitspng \-fs 0.2 \-o reduced.png colour.fits
.PP
Select the specified band from colour FITS (with help of FITS file name
extension):
$ fitspng colour.fits[3] \-o green.png
$ fitspng \-o green.png "colour.fits[1]"
.PP
Create thumbnails:
bash$ for A in *.fits; do fitspng \-s 10 $A \-o ${A%fits}png; done
$ fitspng -s 10 *.fits
.SH AUTHOR
Filip Hroch <hroch@physics.muni.cz>
.SH SEE ALSO
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
FITSPNG
Copyright (C) 2006-2017 Filip Hroch, Masaryk University, Brno, CZ
Copyright (C) 2006-2019 Filip Hroch, Masaryk University, Brno, CZ
Fitspng is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,5 +19,18 @@
*/
/* qmed.c */
extern float qmed(int, float *, int);
/* fitspng.c */
int fitspng(char *, char *,int,float,float,int,
float,float,float,float,float,int,float,int,float,
int,int,int,int);
/* cielab.c */
void XYZ_Lab(float, float, float,float *, float *, float *);
void Lab_XYZ(float, float, float,float *, float *, float *);
/* ecdf.c */
int ecdf(long, const float *, float *, float *);
float quantile(long, const float *, const float *, float);
/* tone.c */
int tone(long, const float *, float, float,float *, float *,int);
This diff is collapsed.
imagedir = $(htmldir)/images
dist_image_DATA = IMG_5952.png IMG_5952_fr10.png IMG_5952_s05.png IMG_5952_a.png \
IMG_5952_fr50.png IMG_5952_s15.png IMG_5952_fn.png IMG_5952_ph.png
dist_image_DATA = IMG_5952.png IMG_5952_fr10.png IMG_5952_s05.png \
IMG_5952_a.png IMG_5952_fr50.png IMG_5952_s15.png \
IMG_5952_fn.png IMG_5952_ph.png itt.svg bcdf.svg bhist.svg
......@@ -236,8 +236,9 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
imagedir = $(htmldir)/images
dist_image_DATA = IMG_5952.png IMG_5952_fr10.png IMG_5952_s05.png IMG_5952_a.png \
IMG_5952_fr50.png IMG_5952_s15.png IMG_5952_fn.png IMG_5952_ph.png
dist_image_DATA = IMG_5952.png IMG_5952_fr10.png IMG_5952_s05.png \
IMG_5952_a.png IMG_5952_fr50.png IMG_5952_s15.png \
IMG_5952_fn.png IMG_5952_ph.png itt.svg bcdf.svg bhist.svg
all: all-am
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
FITSPNG FITS to PNG converter
Copyright (C) 2006-2017 Filip Hroch, Masaryk University, Brno, CZ
Copyright (C) 2006-2019 Filip Hroch, Masaryk University, Brno, CZ
Fitspng is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -18,6 +18,7 @@
*/
#include "fitspng.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
......@@ -26,32 +27,38 @@
#include <assert.h>
#if defined _WIN32 || defined __CYGWIN__
#define DIRSEP '\\'
#else
#define DIRSEP '/'
#endif
void help();
void version();
int fitspng(char *, char *,int,float,float,int,float,float,float,
float,float,int,float,float,float,int,float,int,int,int);
char *pngsuff(const char *);
int main(int argc,char *argv[])
{
char *fits = NULL, *png = "fitspng.png";
char *png = NULL;
int bit_depth, scale, type, verb;
float u,v,t,s,f,z,st,ss, satur = 1.0;
int i, set_fl, set_fn, dcspace = 0;
float xw = 0.2009; /* for D65 and 2 deg. observer */
float yw = 0.4610;
float qblack,rsense,t,s,f0,fz,st,ss, satur;
int i, set_fl, set_fn, set_satur, dcspace = 0;
int nfits = 0;
int status = 0;
bit_depth = 8;
scale = 1;
type = 0;
verb = 0;
set_fl = 0; set_fn = 0;
set_fl = 0; set_fn = 0; set_satur = 0;
u = 0.5;
v = 15.0;
qblack = 0.25;
rsense = 1.0;
t = 0.0;
s = 1.0;
f = 1.0;
z = 0.0;
f0 = 1.0;
fz = 0.0;
satur = 1.0;
if( argc == 1 ) {
help();
......@@ -98,22 +105,6 @@ int main(int argc,char *argv[])
if( strcmp(argv[i],"linear") == 0 )
type = 0;
/* asinh */
else if( strcmp(argv[i],"asinh") == 0 )
type = 1;
/* magnitude */
else if( strcmp(argv[i],"log") == 0 )
type = 2;
/* gamma */
else if( strcmp(argv[i],"gamma") == 0 )
type = 3;
/* error function */
else if( strcmp(argv[i],"normal") == 0 )
type = 4;
/* square root */
else if( strcmp(argv[i],"sqrt") == 0 )
type = 5;
......@@ -126,14 +117,6 @@ int main(int argc,char *argv[])
else if( strcmp(argv[i],"logistic") == 0 )
type = 7;
/* atan */
else if( strcmp(argv[i],"atan") == 0 )
type = 8;
/* ratio */
else if( strcmp(argv[i],"ratio") == 0 )
type = 9;
else {
fprintf(stderr,"A wrong type of conversion specified.\n");
return(1);
......@@ -142,7 +125,7 @@ int main(int argc,char *argv[])
/* intensity scale */
else if( strcmp(argv[i],"-f0") == 0 && i++ < argc ){
if( sscanf(argv[i],"%f",&f) != 1 && f > 0.0 ) {
if( sscanf(argv[i],"%f",&f0) != 1 && f0 > 0.0 ) {
fprintf(stderr,"-f0: Specify a positive real number.\n");
return(1);
}
......@@ -150,7 +133,7 @@ int main(int argc,char *argv[])
/* zero point */
else if( strcmp(argv[i],"-fz") == 0 && i++ < argc ){
if( sscanf(argv[i],"%f",&z) != 1 ) {
if( sscanf(argv[i],"%f",&fz) != 1 ) {
fprintf(stderr,"-fz: Specify a real number.\n");
return(1);
}
......@@ -167,8 +150,8 @@ int main(int argc,char *argv[])
/* relative intensity scale */
else if( strcmp(argv[i],"-fr") == 0 && i++ < argc ){
if( sscanf(argv[i],"%f,%f",&u,&v) != 2 && v > 0.0 ) {
fprintf(stderr,"-fr: Specify a pair of real numbers separated by comma (second positive).\n");
if( sscanf(argv[i],"%f,%f",&qblack,&rsense) != 2 && rsense > 0.0 ) {
fprintf(stderr,"-fr: Specify a pair of real numbers separated by comma (firs should be 0 .. 1, second positive).\n");
return(1);
}
}
......@@ -179,14 +162,7 @@ int main(int argc,char *argv[])
fprintf(stderr,"-fs: Specify a positive (or zero) real number.\n");
return(1);
}
}
/* white point */
else if( strcmp(argv[i],"-fw") == 0 && i++ < argc ){
if( sscanf(argv[i],"%f,%f",&xw,&yw) != 2 ) {
fprintf(stderr,"-fw: Specify a pair of real numbers separated by comma (both positive).\n");
return(1);
}
set_satur = 1;
}
/* display colourspace */
......@@ -228,42 +204,62 @@ int main(int argc,char *argv[])
if( *argv[i] == '-' )
fprintf(stderr,"Warning: an unknown parameter? (%s).\n",argv[i]);
fits = argv[i];
/* keep the index of the first FITS file on command line */
if( nfits == 0 )
nfits = i;
}
}
if( verb )
fprintf(stderr,"Scaling parameters (type=%d): %f %f\n",type,u,v);
if( nfits == 0 ) {
fprintf(stderr,"Error: unspecified FITS file(s).\n");
return 1;
}
if( argc - nfits > 1 && png ) {
fprintf(stderr,"Error: Set of output filename (by -o) is uncompatible"
" with list of FITSes.\n");
return 1;
}
if( verb ) {
fprintf(stderr,"Scaling: qblack=%f rsense=%f\n",qblack,rsense);
fprintf(stderr,"Itt: (type=%d): f0=%f fz=%f\n",type,f0,fz);
}
if( ! fits ) {
fprintf(stderr,"A FITS file is not specified.\n");
return(1);
status = 0;
for( i = nfits; i < argc; i++ ) {
char *pngname = png ? strdup(png) : pngsuff(argv[i]);
int code = fitspng(argv[i],pngname,bit_depth,qblack,rsense,scale,f0,t,s,st,
ss,type,satur,dcspace,fz,verb,!set_fl,set_fn,set_satur);
if( code != 0 ) {
status = 2;
fprintf(stderr,"Error: fitspng failed for `%s'.\n",argv[i]);
}
free(pngname);
}
return(fitspng(fits,png,bit_depth,u,v,scale,f,t,s,st,ss,type,satur,xw,yw,
dcspace,z,verb,!set_fl,set_fn));
return status;
}
void help()
{
printf("%s\n\n%s\n\n%s\n%s\n%s\n%s\n %s\n%s\n%s\n %s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
printf("%s\n\n%s\n\n%s\n%s\n%s\n%s\n %s\n%s\n %s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"FITSPNG FITS to PNG converter",
"Usage: fitspng [options] file",
"Usage: fitspng [options] file(s)",
"options:",
"\t-f x\t tone function - Func(..): linear (default), asinh, log,",
"\t\t gamma, normal, sqrt, sqr (square), logistic, atan, ratio",
"\t-f0 f\t parameter: f0*Func(..) (default: 1)",
"\t-fz z\t zero parameter: Func(..) + z (default: 0)",
"\t-fr u,v\t scale parameters: (median-u*mad)/(mad/v) (default: 3,1/3)",
"\t-fl t,s\t scale parameters: (x-t)/s",
"\t-f x\t Itt tone function: linear, sqrt, sqr, logistic",
"\t-f0 f\t f0 parameter: f0*f(t)+z0 (default: 1)",
"\t-fz z\t zero z0 parameter: f0*f(t)+z0 (default: 0)",
"\t-fr q,v\t relative scaling parameters: 0<=q<=1, v>0",
"\t-fl B,s\t scale parameters: (x-B)/s",
"\t-fs x\t colour saturation (default: 1)",
"\t-fn st,ss threshold and width for night/day vision (no default)",
"\t-fw x,y\t coordinates of white point",
"\t-fn tn,sn threshold and width for night/day vision (no default)",
"\t-cs x\t output colour-space: sRGB (default) or AdobeRGB",
"\t-s s\t zoom-out image by 1/s, to create thumbnails (default: 1)",
"\t-o\t output filename (default: fitspng.png)",
"\t-o\t output filename (considered for single file input)",
"\t-B\t bits per pixel of output image: 8,16 (default: 8)",
"\t-v\t verbose mode",
"\t--help\t\t give this help",
......@@ -273,10 +269,35 @@ void help()
void version()
{
fprintf(stdout,"FITSPNG, %s, (C) 2006-2017 F. Hroch,"
fprintf(stdout,"FITSPNG, %s, (C) 2006-2019 F. Hroch,"
" Masaryk University in Brno, CZ\n",VERSION);
fprintf(stdout,"FITSPNG comes with ABSOLUTELY NO WARRANTY.\n");
fprintf(stdout,"You may redistribute copies of FITSPNG\n");
fprintf(stdout,"under the terms of the GNU General Public License.\n");
fprintf(stdout,"For more information about these matters, see the file named COPYING.\n");
}
char *pngsuff(const char *fitspath)
{
char *png = 0;
const char *fits = 0, *dot = 0;
/* extracting basename */
if( (fits = strrchr(fitspath,DIRSEP)) == NULL )
fits = fitspath;
else
fits++;
/* suffix like ".fits" is replaced by ".png" */
if( (png = malloc(strlen(fits) + 5)) == NULL )
perror(__FILE__);
*png = '\0'; /* should be initialised with null-terminating byte */
assert(png && fits);
if( (dot = strchr(fits,'.')) != NULL )
strncat(png,fits,dot-fits);
else
strcat(png,fits);
strcat(png,".png");
return png;
}
This diff is collapsed.
This diff is collapsed.
/*
test routine for qmed
*/
#include <stdio.h>
float qmed();
int main()
{
float x[7] = {16.0, 12.0, 99.0, 95.0, 18.0, 87.0, 10.0 };
printf("%f\n",qmed(7,x,4));
return(0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment