28#include "rave_alloc.h"
29#include "rave_debug.h"
32char FmiImageFormatExtension[7][4]={
42int FMI_IMAGE_COMMENT=YES;
56new_image(
int sweep_count)
62 for(i=0; i<sweep_count; i++) {
63 result[i].heights=NULL;
66 result[i].original_nodata=255.0;
67 result[i].original_undetect=0.0;
68 result[i].original_gain=0.5;
69 result[i].original_offset=-32.0;
70 result[i].original_type = RaveDataType_UNDEFINED;
71 result[i].elevation_angle=0.0;
73 result[i].bin_depth=0.0;
74 result[i].type=NULL_IMAGE;
86 img->type = NULL_IMAGE;
87 img->format = UNDEFINED;
91 img->original_type = RaveDataType_UNDEFINED;
92 img->original_nodata=255.0;
93 img->original_undetect=0.0;
94 img->original_gain=0.5;
95 img->original_offset=-32.0;
97 img->elevation_angle = 0.0;
105 img->coord_overflow_handler_x = ZERO;
106 img->coord_overflow_handler_y = ZERO;
107 img->comment_string[0] =
'\0';
111 img->type=TRUE_IMAGE;
112 img->area=img->width*img->height;
113 img->volume=img->area*img->channels;
114 img->array=(Byte *) RAVE_MALLOC(img->volume);
115 img->
original=(
double*) RAVE_MALLOC(img->volume*
sizeof(
double));
116 img->coord_overflow_handler_x=BORDER;
117 img->coord_overflow_handler_y=BORDER;
119 img->comment_string[0]=
'\0';
123int initialize_horz_stripe(
FmiImage *img,
int width){
127 fmi_debug(2,
"initialize_horz_image");
128 initialize_image(img);
129 img->coord_overflow_handler_y=TILE;
133int initialize_vert_stripe(
FmiImage *img,
int height){
137 fmi_debug(2,
"initialize_horz_image");
138 initialize_image(img);
139 img->coord_overflow_handler_x=TILE;
143int link_image_segment(
FmiImage *source,
int start_row,
int rows,
FmiImage *linked){
146 fmi_debug(3,
"link_image_segment");
148 if (start_row+rows > source->height*source->channels)
149 fmi_error(
"link_image_segment: segment overflow");
152 fmi_error(
"link_image_segment: dont-like self-linking");
154 if (linked->type==TRUE_IMAGE)
155 fmi_debug(3,
"WARNING: true image to link image without reset (free)");
157 copy_image_properties(source,linked);
160 linked->area=linked->width*linked->height;
161 linked->volume=linked->area*linked->channels;
162 linked->type=LINK_IMAGE;
163 linked->array=&(source->array[start_row*source->width]);
164 linked->heights=NULL;
171 link_image_segment(source,channel*source->height,1*source->height,linked);
177 fmi_error(
"split_to_link_array: zero channels?");
178 for (k=0;k<segments;k++){
179 ht = source->heights[k] * source->channels;
180 link_image_segment(source,hs,ht,&target[k]);
183 target->sweep_count = segments;
186void split_to_channels(
FmiImage *target,
int channels){
189 fmi_error(
"split_to_channels: zero channels?");
190 hs=(target->height*target->channels);
192 fmi_error(
"split_to_channels: height not divisible by #channels ");
194 target->channels=channels;
195 target->height=hs/channels;
196 target->area=target->height*target->width;
198 fprintf(stderr,
"split_to_channels: %d channels\n",channels);
207 fmi_debug(3,
"concat base");
208 copy_image_properties(source,target);
209 target->sweep_count = count;
210 target->heights = (
int *)RAVE_MALLOC(
sizeof(
int) * count);
211 if (FMI_DEBUG(3)) image_info(target);
213 for (k=1;k<count;k++){
214 if (FMI_DEBUG(3)) fprintf(stderr,
"concatenating #%d\n",k);
215 if (FMI_DEBUG(3)) image_info(&source[k]);
216 if (source[k].width!=target->width)
217 fmi_error(
"concatenate_images: not implemented for variable width");
218 if (source[k].channels!=target->channels)
219 fmi_error(
"concatenate_images: not implemented for variable channel counts");
220 target->height+=source[k].height;
221 target->heights[k-1] = source[k].height;
223 fmi_debug(3,
"to be concat");
224 if (FMI_DEBUG(3)) image_info(target);
225 initialize_image(target);
226 if (FMI_DEBUG(3)) image_info(target);
229 for (k=0;k<count;k++){
230 for (i=0;i<source[k].volume;i++)
231 target->array[j+i]=source[k].array[i];
247 target->width = sample->width;
248 target->height = sample->height;
249 target->channels = sample->channels;
250 target->max_value = sample->max_value;
251 target->sweep_count = sample->sweep_count;
252 target->bin_depth = sample->bin_depth;
253 target->elevation_angle = sample->elevation_angle;
254 target->original_nodata = sample->original_nodata;
255 target->original_undetect = sample->original_undetect;
256 target->original_gain = sample->original_gain;
257 target->original_offset = sample->original_offset;
258 target->original_type = sample->original_type;
260 if(sample->heights == NULL)
261 target->heights = NULL;
264 target->heights = (
int*)RAVE_MALLOC(sample->sweep_count *
sizeof(
int));
265 memcpy(target->heights, sample->heights, sample->sweep_count *
sizeof(
int));
269 target->coord_overflow_handler_x=sample->coord_overflow_handler_x;
270 target->coord_overflow_handler_y=sample->coord_overflow_handler_y;
272 target->area=target->width*target->height;
273 target->volume=target->channels*target->area;
280 if (target->width!=sample->width){
283 fmi_debug(2,
"check_image_properties: unequal widths");
287 if (target->height!=sample->height){
290 fmi_debug(2,
"check_image_properties: unequal heights");
294 if (target->channels!=sample->channels){
295 fmi_debug(2,
"check_image_properties: unequal channel counts");
298 target->max_value=sample->max_value;
299 target->area=target->width*target->height;
300 target->volume=target->channels*target->area;
301 target->original_nodata = sample->original_nodata;
302 target->original_undetect = sample->original_undetect;
303 target->original_gain = sample->original_gain;
304 target->original_offset = sample->original_offset;
305 target->original_type = sample->original_type;
311 fmi_debug(2,
"canonize_image?");
312 if (!check_image_properties(sample,target)){
313 fmi_debug(2,
"canonize_image: YES");
314 copy_image_properties(sample, target);
315 initialize_image(target);
317 fmi_debug(2,
"canonize_image END");
322 switch (image->type){
324 RAVE_FREE(image->array);
332 image->sweep_count=0;
333 image->bin_depth=0.0;
334 image->elevation_angle=0.0;
335 image->original_type = RaveDataType_UNDEFINED;
336 image->original_nodata = 255.0;
337 image->original_undetect = 0.0;
338 image->original_gain = 0.5;
339 image->original_offset = -32.0;
340 RAVE_FREE(image->array);
342 RAVE_FREE(image->heights);
343 image->type=NULL_IMAGE;
346 fprintf(stderr,
" IMAGE TYPE:%d\n",image->type);
347 fmi_error(
"reset_image: unknown image type");
351int legal_coords(
FmiImage *img,
int x,
int y){
354 if (x>=img->width)
return 0;
355 if (y>=img->height)
return 0;
359void handle_coord_overflow(
FmiImage *img,
int *x,
int *y){
362 switch (img->coord_overflow_handler_x){
363 case MIRROR: *x=-*x;
break;
364 case WRAP : *x=*x+img->width;
break;
365 case TILE : *x=*x%img->width;
break;
366 case BORDER: *x=0;
break;
367 default: fmi_error(
"get: coord x underflow");}
369 switch (img->coord_overflow_handler_x){
370 case MIRROR: *x=2*img->width-*x;
break;
371 case WRAP : *x=*x-img->width;
break;
372 case TILE : *x=*x%img->width;
break;
373 case BORDER: *x=img->width-1;
break;
374 default: fmi_error(
"get: coord x overflow");}
376 switch (img->coord_overflow_handler_y){
377 case MIRROR: *y=-*y;
break;
378 case WRAP : *y=*y+img->height;
break;
379 case TILE : *y=*y%img->height;
break;
380 case BORDER: *y=0;
break;
381 default: fmi_error(
"get: coord y underflow");}
383 switch (img->coord_overflow_handler_y){
384 case MIRROR: *y=2*img->height-*y;
break;
385 case WRAP : *y=*y-img->height;
break;
386 case TILE : *y=*y%img->height;
break;
387 case BORDER: *y=img->height-1;
break;
388 default: fmi_error(
"get: coord y overflow");}
391Byte get_pixel_direct(
FmiImage *img,
int address){
392 return img->array[address];
395void put_pixel(
FmiImage *img,
int x,
int y,
int channel,Byte c){
396 handle_coord_overflow(img,&x,&y);
397 img->array[channel*img->area + y*img->width + x]=c;
401void put_pixel_orig(
FmiImage *img,
int x,
int y,
int channel,
double c){
402 handle_coord_overflow(img,&x,&y);
403 img->
original[channel*img->area + y*img->width + x]=c;
407void put_pixel_direct(
FmiImage *img,
int address,Byte c){
408 img->array[address]=c;
411void put_pixel_direct_inc(
FmiImage *img,
int address){
412 if (img->array[address]<255)
413 ++(img->array[address]);
416void put_pixel_or(
FmiImage *img,
int x,
int y,
int channel,Byte c){
417 static Byte *location;
418 handle_coord_overflow(img,&x,&y);
419 location=&(img->array[channel*img->area + y*img->width + x]);
420 *location=*location|c;
423void put_pixel_and(
FmiImage *img,
int x,
int y,
int channel,Byte c){
424 static Byte *location;
425 handle_coord_overflow(img,&x,&y);
426 location=&(img->array[channel*img->area + y*img->width + x]);
427 *location=*location&c;
430void put_pixel_min(
FmiImage *img,
int x,
int y,
int channel,Byte c){
431 static Byte *location;
432 handle_coord_overflow(img,&x,&y);
433 location=&(img->array[channel*img->area + y*img->width + x]);
434 if (c<*location) *location=c;
437void put_pixel_max(
FmiImage *img,
int x,
int y,
int channel,Byte c){
438 static Byte *location;
439 handle_coord_overflow(img,&x,&y);
440 location=&(img->array[channel*img->area + y*img->width + x]);
441 if (c>*location) *location=c;
444Byte get_pixel(
FmiImage *img,
int x,
int y,
int channel){
446 handle_coord_overflow(img,&x,&y);
447 return (img->array[channel*img->area + y*img->width + x]);
450double get_pixel_orig(
FmiImage *img,
int x,
int y,
int channel){
452 handle_coord_overflow(img,&x,&y);
453 return (img->
original[channel*img->area + y*img->width + x]);
456void fill_image(
FmiImage *img,Byte c){
458 img->area=img->width*img->height;
459 img->volume=img->area*img->channels;
460 for (i=0;i<img->volume;i++)
464void fill_image_orig(
FmiImage *img,
double c){
466 img->area=img->width*img->height;
467 img->volume=img->area*img->channels;
468 for (i=0;i<img->volume;i++)
473void image_fill_random(
FmiImage *img,Byte mean,Byte amplitude){
475 img->area=img->width*img->height;
476 img->volume=img->area*img->channels;
477 for (i=0;i<img->volume;i++)
478 img->array[i]=mean+(amplitude*(rand()&255))/256;
483 img->area=img->width*img->height;
484 img->volume=img->area*img->channels;
485 for (i=0;i<img->volume;i++)
486 img->array[i]=img->array[i]^255;
489void limit_image_intensities(
FmiImage *img,Byte min,Byte max){
491 img->area=img->width*img->height;
492 img->volume=img->area*img->channels;
493 for (i=0;i<img->volume;i++){
494 if (img->array[i]<min) img->array[i]=min;
495 else if (img->array[i]>max) img->array[i]=max;}
498void translate_intensity(
FmiImage *img,Byte from,Byte to){
500 img->area=img->width*img->height;
501 img->volume=img->area*img->channels;
502 for (i=0;i<img->volume;i++)
503 if (img->array[i]==from) img->array[i]=to;
510 if (check_image_properties(source,source2)==0)
511 fmi_error(
"subtract_image: incompatible images");
512 canonize_image(source,target);
513 for (i=0;i<target->volume;i++){
514 sum=source->array[i]+source2->array[i];
515 target->array[i]=(sum<=254 ? sum : 254);}
520 if (check_image_properties(source,source2)==0)
521 fmi_error(
"subtract_image: incompatible images");
522 canonize_image(source,target);
523 for (i=0;i<target->volume;i++)
524 target->array[i]=(source->array[i]>source2->array[i]) ? source->array[i]-source2->array[i] : 0;
530 if (check_image_properties(source,source2)==0)
531 fmi_error(
"subtract_image: incompatible images");
532 canonize_image(source,target);
533 for (i=0;i<target->volume;i++)
534 target->array[i]=(255+source->array[i]-source2->array[i])/2;
541 if (check_image_properties(source,source2)==0)
542 fmi_error(
"subtract_image: incompatible images");
543 canonize_image(source,target);
544 for (i=0;i<target->volume;i++){
545 sum=(source->array[i]+source2->array[i])/2;
546 target->array[i]=(sum<=254 ? sum : 254);}
552 if (check_image_properties(source,source2)==0)
553 fmi_error(
"multiply_image255: incompatible images");
554 canonize_image(source,target);
555 for (i=0;i<target->volume;i++){
556 c=source->array[i]*source2->array[i]/255;
557 target->array[i]=MIN(c,255);}
562 canonize_image(source,target);
563 for (i=0;i<source->width;i++)
564 for (j=0;j<source->height;j++){
565 c=get_pixel(source,i,j,0)*get_pixel(source2,i,j,0)/255;
566 put_pixel(target,i,j,0,MIN(c,255));
572 const int half_width=128*128;
573 if (check_image_properties(source,source2)==0)
574 fmi_error(
"multiply_image255_sigmoid: incompatible images");
575 canonize_image(source,target);
576 for (i=0;i<target->volume;i++)
577 target->array[i]=pseudo_sigmoid(half_width,source->array[i]*source2->array[i]);
583 if (check_image_properties(source,source2)==0)
584 fmi_error(
"subtract_image: incompatible images");
585 canonize_image(source,target);
586 for (i=0;i<target->volume;i++)
587 target->array[i]=(source->array[i]>source2->array[i]) ? source->array[i] : source2->array[i];
592 if (check_image_properties(source,source2)==0)
593 fmi_error(
"subtract_image: incompatible images");
594 canonize_image(source,target);
595 for (i=0;i<target->volume;i++)
596 target->array[i]=(source->array[i]<source2->array[i]) ? source->array[i] : source2->array[i];
599void multiply_image_scalar255(
FmiImage *img,
int coeff){
602 for (i=0;i<img->volume;i++){
603 temp=img->array[i]*coeff/255;
604 img->array[i]=MIN(temp,255);}
607void semisigmoid_image(
FmiImage *source,
int half_width){
609 for (i=0;i<source->volume;i++)
610 source->array[i]=pseudo_sigmoid(half_width,source->array[i]);
613void semisigmoid_image_inv(
FmiImage *source,
int half_width){
615 for (i=0;i<source->volume;i++)
616 source->array[i]=255-pseudo_sigmoid(half_width,source->array[i]);
620void sigmoid_image(
FmiImage *source,
int threshold,
int slope){
624 for (i=0;i<source->volume;i++)
625 source->array[i]=128+pseudo_sigmoid(slope,source->array[i]-threshold)/2;
629 for (i=0;i<source->volume;i++)
630 source->array[i]=128-pseudo_sigmoid(-slope,source->array[i]-threshold)/2;
634 for (i=0;i<source->volume;i++)
635 source->array[i]=(source->array[i]>threshold)*255;
640void gaussian_image(
FmiImage *source,
int mean,
int half_width){
642 for (i=0;i<source->volume;i++)
643 source->array[i]=pseudo_gauss(half_width,source->array[i]-mean);
648 fmi_debug(4,
" copy_image");
649 canonize_image(source,target);
650 for (i=0;i<source->volume;i++)
651 target->array[i]=source->array[i];
657 fmi_debug(3,__FILE__);
658 fmi_debug(3,
" extract_channel");
659 fmi_debug(4,
" extract_channel: initialize");
661 if (channel>=source->channels) fmi_error(
"extracting nonexistent channel");
662 copy_image_properties(source,target);
664 initialize_image(target);
665 fmi_debug(4,
" extract_channel: extraction");
666 for (i=0;i<source->width;i++)
667 for (j=0;j<source->height;j++)
668 put_pixel(target,i,j,0,get_pixel(source,i,j,channel));
671 fmi_debug(4,
" extract_channel: ...extracted");
676 fmi_debug(2,__FILE__);
677 fmi_debug(2,
" write_channel");
679 if (channel>=target->channels) fmi_error(
"extracting nonexistent channel");
683 for (i=0;i<source->width;i++)
684 for (j=0;j<source->height;j++)
685 put_pixel(target,i,j,channel,get_pixel(source,i,j,0));
691 fmi_debug(2,
"insert");
692 if (source->channels==target->channels)
693 for (k=0;k<source->channels;k++)
694 for (i=0;i<source->width;i++)
695 for (j=0;j<source->height;j++)
696 put_pixel(target,i0+i,j0+j,k,get_pixel(source,i,j,k));
698 if (source->channels==1)
699 for (k=0;k<target->channels;k++)
700 for (i=0;i<source->width;i++)
701 for (j=0;j<source->height;j++)
702 put_pixel(target,i0+i,j0+j,k,get_pixel(source,i,j,0));
704 fprintf(stderr,
"channels = %d vs %d",source->channels,target->channels);
705 fmi_error(
"insert: channel number conflict");}
712 fmi_debug(1,
"compose2x2");
713 t1=source_ul->width+source_ur->width;
714 t2=source_ll->width+source_lr->width;
715 target->width=MAX(t1,t2);
718 t1=source_ul->height+source_ll->height;
719 t2=source_ur->height+source_lr->height;
720 target->height=MAX(t1,t2);
723 target->channels=MAX(source_ul->channels,source_ur->channels);
724 target->channels=MAX(target->channels,source_ll->channels);
725 target->channels=MAX(target->channels,source_lr->channels);
726 initialize_image(target);
728 if (FMI_DEBUG(3)) image_info(target);
729 fill_image(target,251);
731 insert(source_ul,target,0,0);
732 insert(source_ur,target,tw-source_ur->width,0);
733 insert(source_ll,target,0,th-source_ll->height);
734 insert(source_lr,target,tw-source_lr->width,th-source_lr->height);
740 fmi_debug(1,
"compose2x2");
741 t1=source_ul->width+source_um->width+source_ur->width;
742 t2=source_ll->width+source_lm->width+source_lr->width;
743 target->width=MAX(t1,t2);
746 t1=source_ul->height+source_ll->height;
747 t2=source_um->height+source_lm->height;
748 t3=source_ur->height+source_lr->height;
750 target->height=MAX(t2,t3);
753 target->channels=MAX(source_ul->channels,source_ur->channels);
754 target->channels=MAX(target->channels,source_um->channels);
755 target->channels=MAX(target->channels,source_ll->channels);
756 target->channels=MAX(target->channels,source_lm->channels);
757 target->channels=MAX(target->channels,source_lr->channels);
758 initialize_image(target);
759 fmi_debug(1,
"compose3x2 target:");
760 if (FMI_DEBUG(3)) image_info(target);
761 fill_image(target,251);
763 insert(source_ul,target,0,0);
764 insert(source_um,target,source_ul->width,0);
765 insert(source_ur,target,tw-source_ur->width,0);
766 insert(source_ll,target,0,th-source_ll->height);
767 insert(source_lm,target,source_ll->width,th-source_lr->height);
768 insert(source_lr,target,tw-source_lr->width,th-source_lr->height);
779FmiImageFormat process_image_header(
FmiImage *img,FILE *fp){
781 char str[MAX_COMMENT_LENGTH];
787 img->format=(FmiImageFormat)(c-
'0');
789 switch (img->format){
800 default: fmi_error(
"Not a PNM image");}
802 if (FMI_DEBUG(2)) fprintf(stderr,
"Image type: P%c (%d)\n",c,img->format);
807 while ((c==
' ')||(c==
'\t')||(c==
'\n'));
813 img->comment_string[0]=
'\0';
814 while ((c=getc(fp))==
'#'){
820 fgets(str,MAX_COMMENT_LENGTH-1,fp);
821 if (strlen(img->comment_string)+strlen(str)<MAX_COMMENT_LENGTH)
822 strcat(img->comment_string,str);
824 fmi_debug(1,
"read_image, image comment overflow");
826 fprintf(stderr,
"%s\n",str);
837 fscanf(fp,
"%d %d",&(img->width),&(img->height));
838 if ((img->format==PBM_RAW)||(img->format==PBM_ASC))
841 fscanf(fp,
"%d",&(img->max_value));
843 if (FMI_DEBUG(3)) image_info(img);
848 while ((c==
' ')||(c==
'\t')||(c==
'\n'));
851 fmi_error(
"Unimplemented image format");
857void read_image(
char *filename,
FmiImage *img){
860 FmiImageFormat format;
864 fprintf(stderr,
" reading file: ");fflush(stderr);
865 fprintf(stderr,
"%s\n",filename);
868 if (strcmp(filename,
"-")==0)
871 fp = fopen(filename,
"r");
872 if (fp==NULL) fmi_error(
"read_image: file error");
874 format=process_image_header(img,fp);
876 initialize_image(img);
884 read_pnm_image(fp,img,format);
887 fmi_error(
"read_image: unimplemented image format");}
890void read_pnm_image(FILE *fp,
FmiImage *img,FmiImageFormat format){
896 for (j=0;j<img->height;j++){
899 for (i=0;i<img->width;i++){
903 put_pixel(img,i,j,0,((c&k)>0)?1:254);
910 for (j=0;j<img->height;j++)
911 for (i=0;i<img->width;i++)
912 put_pixel(img,i,j,0,getc(fp));
915 for (j=0;j<img->height;j++)
916 for (i=0;i<img->width;i++){
919 put_pixel(img,i,j,0,(Byte)l);
923 for (j=0;j<img->height;j++)
924 for (i=0;i<img->width;i++)
926 put_pixel(img,i,j,k,getc(fp));
930 for (j=0;j<img->height;j++)
931 for (i=0;i<img->width;i++)
935 put_pixel(img,i,j,0,(Byte)k);
939 fmi_error(
"Error: unimplemented image file type");}
943void write_image(
char *filename,
FmiImage *img,FmiImageFormat format){
944 char *actual_filename;
946 fmi_debug(1,
"write_image: ");
947 fmi_debug(2,filename);
951 if (file_extension(filename)!=NULL)
952 actual_filename=filename;
954 actual_filename=(
char *)RAVE_MALLOC(strlen(filename)+5);
955 strcpy(actual_filename,filename);
956 strcat(actual_filename,
".");
957 strncat(actual_filename,FmiImageFormatExtension[format],4);
959 fmi_debug(1,actual_filename);
960 fp = fopen(actual_filename,
"w");
962 if ((format>=PGM_ASC)&&(format<=PPM_RAW))
963 write_pnm_image(fp,img,format);
965 fmi_error(
"Unsupported image format.");
967 fmi_debug(2,
"write_image: ok");
970 fmi_error(
"Failed opening file for writing.");
971 RAVE_FREE(actual_filename);
974void dump_comments(FILE *fp,
char *comment,
char *begin_code,
char *end_code,
int line_length){
981 for (i=0;i<=len;i++){
983 fprintf(fp,
"%s", begin_code);
985 if (l==line_length-1){
986 fprintf(fp,
"%c\\%s",c,end_code);
989 if ((c==
'\n')||(i==len)){
991 fprintf(fp,
"%s", end_code);
999void write_pnm_image(FILE *fp,
FmiImage *img,FmiImageFormat format){
1003 fprintf(fp,
"P%d\n",format);
1006 trchr(fmi_util_comment,
'\\',
'\n');
1007 dump_comments(fp,fmi_util_comment,
"# ",
"\n",1023);
1008 if (strlen(img->comment_string)>0)
1009 dump_comments(fp,img->comment_string,
"# [",
"]\n",1023);
1010 dump_comments(fp,fmi_util_command_line,
"# ",
"\n",1023);
1011 if (FMI_IMAGE_COMMENT)
1013 fprintf(fp,
"# CREATOR: %s\n",FMI_IMAGE_VER);
1019 fprintf(fp,
"%d %d\n",img->width,img->height);
1020 fprintf(fp,
"%d\n",img->max_value);
1024 if (img->channels!=1)
1025 fmi_error(
"write_pnm_image: PBM implies 1 channel");
1026 for (j=0;j<img->height;j++){
1029 for (i=0;i<img->width;i++){
1030 c=(c|(((get_pixel(img,i,j,0)&128)==0)?0:k));
1039 if (img->channels!=1)
1040 fmi_error(
"write_pnm_image: PGM implies 1 channel");
1041 for (j=0;j<img->height;j++)
1042 for (i=0;i<img->width;i++)
1043 fputc(get_pixel(img,i,j,0),fp);
1046 if (img->channels!=3)
1047 fmi_error(
"write_pnm_image: PPM implies 3 channels");
1048 for (j=0;j<img->height;j++)
1049 for (i=0;i<img->width;i++)
1051 fputc(get_pixel(img,i,j,k),fp);
1062 fprintf(stderr,
" type: ");
1064 case NULL_IMAGE: fprintf(stderr,
"NULL_IMAGE\n");
break;
1065 case TRUE_IMAGE: fprintf(stderr,
"TRUE_IMAGE\n");
break;
1066 case LINK_IMAGE: fprintf(stderr,
"LINK_IMAGE\n");
break;
1068 fprintf(stderr,
" channels: %d\n",img->channels);
1069 fprintf(stderr,
" width: %d\n",img->width);
1070 fprintf(stderr,
" height: %d\n",img->height);
1071 fprintf(stderr,
" area: %d\n",img->area);
1072 fprintf(stderr,
" volume: %d\n",img->volume);
1073 fprintf(stderr,
" max_val: %d\n",img->max_value);
1085 fmi_debug(1,
"fmi_image.c: expand_channel_to_rgb");
1087 copy_image_properties(source,target);
1089 initialize_image(target);
1091 for (i=0;i<source->width;i++)
1092 for (j=0;j<source->height;j++){
1093 c=get_pixel(source,i,j,channel);
1095 put_pixel(target,i,j,k,c);
1099void map_channel_to_colors(
FmiImage *source,
int channel,
FmiImage *target,
int map_size,ColorMap map){
1102 fmi_debug(4,
"fmi_image.c: map_channel_to_channels");
1103 if (map_size>255) fmi_error(
"map_channel_to_channels: too many levels");
1110 copy_image_properties(source,target);
1112 initialize_image(target);
1114 for (i=0;i<source->width;i++)
1115 for (j=0;j<source->height;j++){
1116 c=get_pixel(source,i,j,channel);
1117 for (l=0;l<map_size;l++){
1120 put_pixel(target,i,j,k,map[l][k+1]);
1126void map_channel_to_256_colors(
FmiImage *source,
int channel,
FmiImage *target,ColorMap256 map){
1129 fmi_debug(4,
"fmi_image.c: map_channel_to_256_colors");
1136 copy_image_properties(source,target);
1138 initialize_image(target);
1140 for (i=0;i<source->width;i++)
1141 for (j=0;j<source->height;j++)
1143 put_pixel(target,i,j,k,map[get_pixel(source,i,j,channel)][k]);
1147void map_256_colors_to_gray(
FmiImage *source,
FmiImage *target,ColorMap256 map){
1150 fmi_debug(4,
"fmi_image.c: map_256_colors_to_gray");
1151 copy_image_properties(source,target);
1153 initialize_image(target);
1154 fill_image(target,0);
1156 for (i=0;i<source->width;i++)
1157 for (j=0;j<source->height;j++){
1158 r=get_pixel(source,i,j,0);
1159 g=get_pixel(source,i,j,1);
1160 b=get_pixel(source,i,j,2);
1162 if ((map[l][0]==r)&&(map[l][1]==g)&&(map[l][2]==b)){
1163 put_pixel(target,i,j,0,l);
1169void read_colormap256(
char *filename,ColorMap256 map){
1172 fmi_debug(4,
"read_colormap256");
1173 fmi_debug(5,filename);
1174 fp = fopen(filename,
"r");
1175 if (!fp) fmi_error(
"read_colormap256: file read error");
1177 if ((c=getc(fp))==
'#'){
1180 while ((
char)(c=getc(fp))!=
'\n'){
1182 if (c==EOF) fmi_error(
"read_colormap256: only comments?");
1184 }
while ((c=getc(fp))==
'#');
1190 fmi_debug(5,
"read_colormap256: colors");
1192 while (fscanf(fp,
"%d",&c)!=EOF)
1193 fscanf(fp,
"%d %d %d\n",(
int*)&map[c][0],(
int*)&map[c][1],(
int*)&map[c][2]);
1195 fmi_debug(5,
"read_colormap256 complete");
1200 int i,j,k,i0,j0,max_radius,di,dj,radius,a;
1201 target->width=source->width;
1202 target->height=source->width;
1203 target->heights=NULL;
1204 target->max_value=255;
1205 target->channels=source->channels;
1206 initialize_image(target);
1210 fmi_debug(3,
"to_cart");
1213 max_radius=target->width;
1215 j0=target->height/2;
1217 for (i=0;i<target->width;i++){
1219 for (j=0;j<target->height;j++){
1221 radius=2*(int)sqrt((
double)(di*di+dj*dj));
1222 for (k=0;k<target->channels;k++){
1223 if (radius<=max_radius){
1225 a=180*atan2(di,-dj)/3.14;
1227 put_pixel(target,i,j,k,get_pixel(source,radius,a,k));
1230 }
else put_pixel(target,i,j,k,255);
1237void clear_histogram(Histogram hist){
1239 for (i=0;i<HISTOGRAM_SIZE;i++) hist[i]=0;
1242void calc_histogram(
FmiImage *source,Histogram hist){
1244 clear_histogram(hist);
1245 for (i=0;i<source->volume;i++)
1246 ++hist[source->array[i]];
1249void output_histogram(FILE *fp,Histogram hist){
1251 for (i=0;i<HISTOGRAM_SIZE;i++)
1253 fprintf(fp,
"%d\t%ld\n",i,hist[i]);
1256void write_histogram(
char *filename,Histogram hist){
1258 fp=fopen(filename,
"w");
1259 output_histogram(fp,hist);
1263void dump_histogram(Histogram hist){
1264 output_histogram(stdout,hist);