1 /*----------------------------------------------------------------------
2     Line-preserving smoothing                   lpsmooth  ver 1.2
3         Written by  H.Goto, Apr  2000
4         Modified by H.Goto, July 2000
5         Modified by H.Goto, Sep  2000
6         Modified by H.Goto, Feb  2002
7 ----------------------------------------------------------------------*/
8 
9 /*--------------------------------------------------------------------
10   Copyright (C) 2000-2002  Hideaki Goto
11 
12         All Rights Reserved
13 
14   Permission to use, copy, modify, and distribute this software and
15   its documentation for any purpose is hereby granted without fee,
16   provided that (i) the above copyright notice and this permission
17   notice appear in all copies and in supporting documentation, (ii)
18   the name of the author, Hideaki Goto, may not be used in any
19   advertising or otherwise to promote the sale, use or other
20   dealings in this software without prior written authorization
21   from the author, (iii) this software may not be used for
22   commercial products without prior written permission from the
23   author, and (iv) the notice of the modification is specified in
24   case of that the modified copies of this software are distributed.
25 
26   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
27   THE AUTHOR WILL NOT BE RESPONSIBLE FOR ANY DAMAGE CAUSED BY THIS
28   SOFTWARE.
29 --------------------------------------------------------------------*/
30 
31 #define		DefaultProcessCount	1
32 #define		DefaultCenterWeight	1
33 #define		DefaultPixels		3
34 
35 #include        <stdio.h>
36 #include        <stdlib.h>
37 #include        <string.h>
38 
39 #include	"utypes.h"
40 
41 #include	"ufilep.h"
42 #include	"siplib.h"
43 #include	"xiplib.h"
44 
45 static int	sw_verbose = 0;
46 
47 
48 
49 
50 /*----------------------------------------------
51     Load PGM image file
52 ----------------------------------------------*/
53 
load_image(char * fname,SIPImage ** image,int * width,int * height)54 static int load_image(char *fname,SIPImage **image,int *width,int *height){
55 	PBMFILE	PBMLD;
56 	int	retcode,depth,x,y;
57 	SIPImage	*imgbuf;
58 	int	bufwidth,bufheight,bufdepth;
59 	uchar	*lbuf,*src,*dst;
60 	*image = 0;	/* default value = NULL */
61 	PBMLD.setpal_fb(0,0xff);
62 	retcode = PBMLD.open(fname,"r");
63 	if ( retcode )  return(retcode);
64 	switch ( PBMLD.getfiletype() ){
65 	  case 0:	depth = 1;  bufdepth = 8;  break;
66 	  case 1:	depth = 8;  bufdepth = 8;  break;
67 	  case 2:	depth = 32;  bufdepth = 32;  break;	/* 24bit */
68 	  default:	return(-5);
69 	}
70 	*width  = PBMLD.getwidth();
71 	*height = PBMLD.getheight();
72 
73 	bufwidth  = *width;
74 	bufheight = *height;
75 
76 	if ( 0 == (lbuf = new uchar[3 * bufwidth]) )  return(-6);
77 	if ( 0 == (imgbuf = sip_CreateImage(bufwidth,bufheight,bufdepth)) ){
78 		delete []lbuf;
79 		return(-6);
80 	}
81 	sip_ClearImage(imgbuf,0xff);
82 	for ( y=0 ; y < *height ; y++ ){
83 		if ( 32 == depth ){
84 			if ( 0 != PBMLD.readline(-1,(void *)lbuf) ){
85 				delete []lbuf;
86 				return(-1);	/* read error */
87 			}
88 			src = lbuf;  dst = (uchar *)sip_getimgptr(imgbuf,y);
89 			for ( x=0 ; x < *width ; x++ ){
90 				dst[0] = src[0];
91 				dst[1] = src[1];
92 				dst[2] = src[2];
93 				dst[3] = 0;
94 				src += 3;  dst += 4;
95 			}
96 		}
97 		else if ( 8 == depth ){
98 			if ( 0 != PBMLD.readline(-1,\
99 				(void *)sip_getimgptr(imgbuf,y)) ){
100 				delete []lbuf;
101 				return(-1);	/* read error */
102 			}
103 		}
104 		else{	if ( 0 != PBMLD.readline_gray(-1,\
105 				(void *)sip_getimgptr(imgbuf,y)) ){
106 				delete []lbuf;
107 				return(-1);	/* read error */
108 			}
109 		}
110 	}
111 	*image = imgbuf;
112 	delete []lbuf;
113 	PBMLD.close();
114 	return(0);
115 }
116 
117 
118 
119 
120 /*----------------------------------------------
121     Print usage
122 ----------------------------------------------*/
123 
usage()124 static void usage(){
125 	fputs("lpsmooth v1.2, Copyright (C) 2000-2002 Hideaki Goto \n",stderr);
126 	fputs("Usage: lpsmooth [-options] in_file out_file \n",stderr);
127 	fputs("         -n N      :  smoothing counts (default N=1) \n",stderr);
128 	fputs("         -w N      :  weight factor for the central pixel (default N=1) \n",stderr);
129 	fputs("         -p N      :  number of the pixels used (1-9) (default N=3) \n",stderr);
130 	fputs("         -verbose  :  show processing information \n",stderr);
131 	fputs("Note:  lpsmooth -w 1 -p 9 ... is identical to calculating \n",stderr);
132 	fputs("       the moving average with a 3x3 mask. \n",stderr);
133 	fputs("       lpsmooth -w 0 -p N ... is identical to the k-nearest neighbor \n",stderr);
134 	fputs("       smoothing with k=N-1. \n",stderr);
135 }
136 
137 
138 
139 
140 /*----------------------------------------------
141     Main routine
142 ----------------------------------------------*/
143 
main(int ac,char * av[])144 int main(int ac,char *av[]){
145 	char	*infile  = NULL;
146 	char	*outfile = NULL;
147 	int	proc_counts = DefaultProcessCount;
148 	int	ctweight = DefaultCenterWeight;
149 	int	pixels = DefaultPixels;
150 	int	width,height;
151 	int	i,k;
152 	SIPImage	*image;
153 
154 	for ( k=1, i=1 ; i<ac && k ; i++ ){
155 		if ( 0 == strcmp("-n",av[i]) ){
156 			if ( i++ >= ac ){  k=0; continue; }
157 			proc_counts = atoi(av[i]);
158 			if ( proc_counts < 1 ){  k=0; continue; }
159 			continue;
160 		}
161 		if ( 0 == strcmp("-w",av[i]) ){
162 			if ( i++ >= ac ){  k=0; continue; }
163 			ctweight = atoi(av[i]);
164 			if ( ctweight < 0 ){  k=0; continue; }
165 			continue;
166 		}
167 		if ( 0 == strcmp("-p",av[i]) ){
168 			if ( i++ >= ac ){  k=0; continue; }
169 			pixels = atoi(av[i]);
170 			if ( pixels < 1 || pixels > 9 ){  k=0; continue; }
171 			continue;
172 		}
173 		if ( 0 == strcmp("-verbose",av[i]) ){  sw_verbose = -1;  continue; }
174 		if ( 0 == strcmp("-v",av[i]) ){  sw_verbose = -1;  continue; }
175 		if ( av[i][0] == '-' && strlen(av[i]) > 1 ){  k=0;  continue; }
176 		if ( NULL == infile ){  infile = av[i];  continue; }
177 		if ( NULL == outfile ){  outfile = av[i];  continue; }
178 	}
179 	if ( k == 0 || outfile == NULL ){  usage();  return(0); }
180 	if ( k == 0 || infile == NULL ){  usage();  return(0); }
181 	if ( pixels == 1 && ctweight == 0 ){  usage();  return(0); }
182 
183 
184 /* ---- Read Image ---- */
185 
186 	if ( 0 > load_image(infile,&image,&width,&height) ){
187 		fprintf(stderr,"Can't read \"%s\".\n",infile);
188 		return(2);
189 	}
190 
191 	if ( sw_verbose ){
192 		fprintf(stderr,"Image size  = %d x %d\n",width,height);
193 		if ( image->depth == 32 ){
194 			fprintf(stderr,"Image depth = 24\n");
195 		}
196 		else{	fprintf(stderr,"Image depth = 8\n");
197 		}
198 	}
199 
200 
201 /* ---- Smoothing ---- */
202 
203 	for ( i=0 ; i<proc_counts ; i++ ){
204 		sip_kNNsmooth(image,image,pixels,ctweight);
205 	}
206 
207 
208 /* ---- Save Image  ---- */
209 
210 	if ( 0 > xip_SaveImage(outfile,image) ){
211 		fprintf(stderr,"Can't write \"%s\".\n",outfile);
212 	}
213 
214 	sip_DestroyImage(image);
215 	return(0);
216 }
217 
218 
219