Total Variation Inpainting using Split Bregman
applymask.c
Go to the documentation of this file.
1 
15 #include <stdio.h>
16 #include <string.h>
17 #include "imageio.h"
18 
20 #define JPEGQUALITY 95
21 
22 
23 void PrintHelpMessage()
24 {
25  puts("Apply an inpainting mask, P. Getreuer, 2012\n\n"
26  "Syntax: applymask <input> <mask> <output>\n");
27  puts("where <input>, <mask>, and <output> are "
28  READIMAGE_FORMATS_SUPPORTED " images.\n");
29  puts("Example:\n"
30  " applymask input.bmp mask.bmp output.bmp\n");
31 }
32 
33 
34 void ApplyMask(unsigned char *Image, int Width, int Height, int NumChannels,
35  const unsigned char *Mask, int MaskWidth, int MaskHeight);
36 int IsGrayscale(const unsigned char *Image, int Width, int Height);
37 
38 
39 int main(int argc, char **argv)
40 {
41  const char *InputFile, *MaskFile, *OutputFile;
42  unsigned char *Image = NULL, *Mask = NULL;
43  int Width, Height, NumChannels, MaskWidth, MaskHeight, Status = 1;
44 
45  if(argc != 4)
46  {
48  return 0;
49  }
50 
51  InputFile = argv[1];
52  MaskFile = argv[2];
53  OutputFile = argv[3];
54 
55  /* Read the input image */
56  if(!(Image = (unsigned char *)ReadImage(&Width, &Height,
57  InputFile, IMAGEIO_RGB | IMAGEIO_PLANAR | IMAGEIO_U8))
58  || !(Mask = (unsigned char *)ReadImage(&MaskWidth, &MaskHeight,
59  MaskFile, IMAGEIO_GRAYSCALE | IMAGEIO_U8)))
60  goto Catch;
61 
62  NumChannels = IsGrayscale(Image, Width, Height) ? 1 : 3;
63 
64  /* Apply the mask */
65  ApplyMask(Image, Width, Height, NumChannels, Mask, MaskWidth, MaskHeight);
66 
67  /* Write the mask image */
68  if(!WriteImage(Image, Width, Height, OutputFile,
69  ((NumChannels == 1) ? IMAGEIO_GRAYSCALE : IMAGEIO_RGB)
70  | IMAGEIO_PLANAR | IMAGEIO_U8, JPEGQUALITY))
71  {
72  fprintf(stderr, "Error writing to \"%s\".\n", OutputFile);
73  goto Catch;
74  }
75 
76  Status = 0;
77 Catch:
78  if(Mask)
79  Free(Mask);
80  if(Image)
81  Free(Image);
82  return Status;
83 }
84 
85 
95 void ApplyMask(unsigned char *Image, int Width, int Height, int NumChannels,
96  const unsigned char *Mask, int MaskWidth, int MaskHeight)
97 {
98  const long NumPixels = ((long)Width) * ((long)Height);
99  long x, y, MinWidth, MinHeight, Channel;
100 
101  MinWidth = (MaskWidth < Width) ? MaskWidth : Width;
102  MinHeight = (MaskHeight < Height) ? MaskHeight : Height;
103 
104  for(Channel = 0; Channel < NumChannels; Channel++, Image += NumPixels)
105  for(y = 0; y < MinHeight; y++)
106  for(x = 0; x < MinWidth; x++)
107  if(Mask[x + MaskWidth*y] >= 128)
108  Image[x + Width*y] = 128;
109 }
110 
111 
113 int IsGrayscale(const unsigned char *Image, int Width, int Height)
114 {
115  const long NumPixels = ((long)Width) * ((long)Height);
116  const unsigned char *Red = Image;
117  const unsigned char *Green = Image + NumPixels;
118  const unsigned char *Blue = Image + 2*NumPixels;
119  long n;
120 
121  for(n = 0; n < NumPixels; n++)
122  if(Red[n] != Green[n] || Red[n] != Blue[n])
123  return 0;
124 
125  return 1;
126 }