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