Table of Contents for
Intermediate C Programming

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Intermediate C Programming by Yung-Hsiang Lu Published by CRC Press, 2015
  1. Front Cover
  2. Contents (1/2)
  3. Contents (2/2)
  4. List of Figures (1/2)
  5. List of Figures (2/2)
  6. List of Tables
  7. Foreword
  8. Preface
  9. Author, Reviewers, and Artist
  10. Rules in Software Development
  11. Source Code
  12. I. Computer Storage: Memory and File
  13. 1. Program Execution (1/2)
  14. 1. Program Execution (2/2)
  15. 2. Stack Memory (1/5)
  16. 2. Stack Memory (2/5)
  17. 2. Stack Memory (3/5)
  18. 2. Stack Memory (4/5)
  19. 2. Stack Memory (5/5)
  20. 3. Prevent, Detect, and Remove Bugs (1/2)
  21. 3. Prevent, Detect, and Remove Bugs (2/2)
  22. 4. Pointers (1/6)
  23. 4. Pointers (2/6)
  24. 4. Pointers (3/6)
  25. 4. Pointers (4/6)
  26. 4. Pointers (5/6)
  27. 4. Pointers (6/6)
  28. 5. Writing and Testing Programs (1/4)
  29. 5. Writing and Testing Programs (2/4)
  30. 5. Writing and Testing Programs (3/4)
  31. 5. Writing and Testing Programs (4/4)
  32. 6. Strings (1/3)
  33. 6. Strings (2/3)
  34. 6. Strings (3/3)
  35. 7. Programming Problems and Debugging (1/4)
  36. 7. Programming Problems and Debugging (2/4)
  37. 7. Programming Problems and Debugging (3/4)
  38. 7. Programming Problems and Debugging (4/4)
  39. 8. Heap Memory (1/3)
  40. 8. Heap Memory (2/3)
  41. 8. Heap Memory (3/3)
  42. 9. Programming Problems Using Heap Memory (1/4)
  43. 9. Programming Problems Using Heap Memory (2/4)
  44. 9. Programming Problems Using Heap Memory (3/4)
  45. 9. Programming Problems Using Heap Memory (4/4)
  46. 10. Reading and Writing Files (1/3)
  47. 10. Reading and Writing Files (2/3)
  48. 10. Reading and Writing Files (3/3)
  49. 11. Programming Problems Using File (1/2)
  50. 11. Programming Problems Using File (2/2)
  51. II. Recursion
  52. 12. Recursion (1/4)
  53. 12. Recursion (2/4)
  54. 12. Recursion (3/4)
  55. 12. Recursion (4/4)
  56. 13. Recursive C Functions (1/4)
  57. 13. Recursive C Functions (2/4)
  58. 13. Recursive C Functions (3/4)
  59. 13. Recursive C Functions (4/4)
  60. 14. Integer Partition (1/5)
  61. 14. Integer Partition (2/5)
  62. 14. Integer Partition (3/5)
  63. 14. Integer Partition (4/5)
  64. 14. Integer Partition (5/5)
  65. 15. Programming Problems Using Recursion (1/5)
  66. 15. Programming Problems Using Recursion (2/5)
  67. 15. Programming Problems Using Recursion (3/5)
  68. 15. Programming Problems Using Recursion (4/5)
  69. 15. Programming Problems Using Recursion (5/5)
  70. III. Structure
  71. 16. Programmer-Defined Data Types (1/6)
  72. 16. Programmer-Defined Data Types (2/6)
  73. 16. Programmer-Defined Data Types (3/6)
  74. 16. Programmer-Defined Data Types (4/6)
  75. 16. Programmer-Defined Data Types (5/6)
  76. 16. Programmer-Defined Data Types (6/6)
  77. 17. Programming Problems Using Structure (1/4)
  78. 17. Programming Problems Using Structure (2/4)
  79. 17. Programming Problems Using Structure (3/4)
  80. 17. Programming Problems Using Structure (4/4)
  81. 18. Linked Lists (1/3)
  82. 18. Linked Lists (2/3)
  83. 18. Linked Lists (3/3)
  84. 19. Programming Problems Using Linked List (1/2)
  85. 19. Programming Problems Using Linked List (2/2)
  86. 20. Binary Search Trees (1/4)
  87. 20. Binary Search Trees (2/4)
  88. 20. Binary Search Trees (3/4)
  89. 20. Binary Search Trees (4/4)
  90. 21. Parallel Programming Using Threads (1/5)
  91. 21. Parallel Programming Using Threads (2/5)
  92. 21. Parallel Programming Using Threads (3/5)
  93. 21. Parallel Programming Using Threads (4/5)
  94. 21. Parallel Programming Using Threads (5/5)
  95. IV. Applications
  96. 22. Finding the Exit of a Maze (1/5)
  97. 22. Finding the Exit of a Maze (2/5)
  98. 22. Finding the Exit of a Maze (3/5)
  99. 22. Finding the Exit of a Maze (4/5)
  100. 22. Finding the Exit of a Maze (5/5)
  101. 23. Image Processing (1/3)
  102. 23. Image Processing (2/3)
  103. 23. Image Processing (3/3)
  104. 24. Huffman Compression (1/10)
  105. 24. Huffman Compression (2/10)
  106. 24. Huffman Compression (3/10)
  107. 24. Huffman Compression (4/10)
  108. 24. Huffman Compression (5/10)
  109. 24. Huffman Compression (6/10)
  110. 24. Huffman Compression (7/10)
  111. 24. Huffman Compression (8/10)
  112. 24. Huffman Compression (9/10)
  113. 24. Huffman Compression (10/10)
  114. A. Linux
  115. B. Version Control
  116. C. Integrated Development Environments (IDE) (1/3)
  117. C. Integrated Development Environments (IDE) (2/3)
  118. C. Integrated Development Environments (IDE) (3/3)
386 Intermediate C Programming
}59
img = malloc ( s i z e o f ( BMP_I mage ) );60
i f ( img == NULL )61
{62
return cleanUp ( fptr , img ) ;63
}64
// read the header65
i f ( fread (& ( img -> header ) , s i z e o f ( B MP_Header ) ,66
1, fptr ) != 1)67
{68
// fread fails69
return cleanUp ( fptr , img ) ;70
}71
i f ( ch eckHeader (& ( img -> header ) ) == 0)72
{73
return cleanUp ( fptr , img ) ;74
}75
img -> data_siz e =76
( img -> header ). size - s i z e o f ( B MP_Header );77
img -> width = ( img -> header ). width ;78
img -> height = ( img -> header ) . height ;79
img -> byt es_per _pixel =80
( img -> header ). bits / B I TS_PER _ BYTE ;81
img -> data =82
malloc ( s i z e o f ( unsigned char ) * ( img -> da t a_size ) );83
i f (( img -> data ) == NULL )84
{85
// malloc fail86
return cleanUp ( fptr , img ) ;87
}88
i f ( fread ( img -> data , s i z e o f ( char) , img -> data_size ,89
fptr ) != ( img -> dat a _size ) )90
{91
// fread fails92
return cleanUp ( fptr , img ) ;93
}94
char onebyte ;95
i f ( fread (& onebyte , s i z e o f ( char) , 1 , fptr ) != 0)96
{97
// not at the of the file but the file still has data98
return cleanUp ( fptr , img ) ;99
}100
// eve rything successf u l101
fclose ( fptr );102
return img ;103
}104
int BMP_save ( const BMP_Image * img , const char * filename )105
{106
FILE * fptr = NULL ;107
fptr = fopen ( filename , " w") ;108
i f ( fptr == NULL )109
Image Processing 387
{110
return 0;111
}112
// write the header first113
i f ( fwrite (& ( img -> header ) , s i z e o f ( BM P_Header ) , 1,114
fptr ) != 1)115
{116
// fwrite fails117
fclose ( fptr );118
return 0;119
}120
i f ( fwrite ( img -> data , s i z e o f ( char), img -> data_size ,121
fptr ) != ( img -> dat a _size ) )122
{123
// fwrite fails124
fclose ( fptr );125
return 0;126
}127
// eve rything successf u l128
fclose ( fptr );129
return 1;130
}131
void BMP_des troy ( BMP_Im age * img )132
{133
free ( img -> data ) ;134
free ( img );135
}136
23.2 Processing Images
In this BMP file format, each pixel uses three bytes representing the three primary
colors of the visible spectrum: red, green, and blue. This is commonly referred to as the
RGB color space. Other color spaces exist and are used for various purposes. Another
common color space is HSV, which stands for hue, saturation, and value, and is useful for
certain transformations. For example, changing the saturation value changes the vibrancy
of the color. The RGB color space is a convenient color space to start because computer
monitors use RGB values. It is not a particularly useful color space for producing natural
blending effects, or for specifying the patterns and amounts of inks to be sprayed when
printing. RGB is simple and can be used for displaying pixels on computer monitors. BMP
images store their pixels in the RGB color space. RGB is an additive color space. When red
and green are combined, the resulting color is yellow. When red and blue are combined, the
resulting color is magenta. When green and blue are combined, the resulting color is cyan.
White is generated by combining all of the colors.
This section explains several methods for processing BMP images. Let’s see some exam-
ples before explaining how they work. Fig. 23.2–Fig. 23.7 are in the color insert.
388 Intermediate C Programming
23.2.1 Image Pixels and Colors
The image’s colors are stored in the data attribute. Every pixel uses three consecutive
bytes. For example, the first pixel uses the first three bytes: data[0], data[1], and data[2].
The second pixel uses data[3], data[4], and data[5]. Among the three elements, the first
byte represents blue, the second represents green, and the third represents red. Thus, the
order is actually BGR (not RGB).
Each data element is a byte and has a value between 0 and 255 (inclusive). Larger values
mean brighter colors. If a given pixel is pure blue, then the first element is non-zero and the
other two elements are zero. If a given pixel is pure red, then the red element is non-zero
and the other two elements are both zero. If all three elements are 255, then the pixel is the
brightest white. If all three elements are 0, then the pixel is black.
Even though an image is two-dimensional, data stores the pixels in a one-dimensional
array. This is the most common method because managing one-dimensional arrays is simpler
than managing two-dimensional arrays.
Each pixel has an (x, y) coordinate. In high school geometry, the origin (0, 0) is the
lower left corner of a graph, the X coordinate increases to the right, and the Y coordinate
increases upward. Computer graphics is generally done with a different coordinate system.
The origin (0, 0) is the top left corner of the image. The X coordinate increases to the
right, and the Y coordinate increases downward. In this coordinate system, we can access
the color values of pixels (x, y) by calculating their index in data. The formula is:
3 × (y × width + x) for blue
3 × (y × width + x) + 1 for green
3 × (y × width + x) + 2 for red
23.2.2 Processing Functions
The following listing is a header file that declares the functions we will consider in the
rest of this chapter.
// bmpfunc .h1
#i f n d e f _BMPFUNC _H_2
#d ef in e _BMP F UNC_H_3
#in clude " bmpimage .h "4
// keep only one color ,5
// clr = 2, keep red6
// clr = 1, keep green7
// clr = 0, keep blue8
void BMP_color ( B M P_Image * image , in t clr ) ;9
// Invert all of the image data in a BMP image10
// ( value = 255 - value )11
void BMP_inve r t ( B MP_Image * image );12
// calc ulate ver t ical edges using the given threshold value13
void B MP_edge ( BMP_Image * image , i n t thrshd );14
// convert an RGB image to a gray - level image15
void B MP_gray ( BMP_Image * image );16
// calc ulate the h istogram of each color17
void BMP_h istogra m ( BMP_Image * image );18
// make a chec k erboard19
void BMP_che cker ( BMP_Im age * image );20
// mix the colors21
void BMP_mix ( BMP_Image * image );22
Image Processing 389
// equaliz e by making the darkest to and bri g htest to 25523
void BMP_eq ualize ( B MP_Image * image );24
#e ndif25
23.2.3 Applying a Color Filter
The first processing function is the color filter BMP Color. The method takes a BMP
image and an integer between 0 and 2. The integer indicates which color will be selected. If
the integer is 0, then blue is selected. Likewise, 1 selects green, and 2 selects red. If a color
is not selected, it is set to zero.
// bmpcolo r . c1
#in clude " bmpfunc . h"2
void BMP_color ( B M P_Image * img , int clr )3
{4
int pxl ;5
for ( pxl = clr ; pxl < ( img -> data_ size ) ; pxl ++)6
{7
// set the other color compon e nts to zero8
i f (( pxl % 3) != clr )9
{10
img -> data [ pxl ] = 0;11
}12
}13
}14
As shown in Fig. 23.2 selecting one color sets the other two colors to zeros, revealing
the contribution of the selected color to the overall image. If the selected color was zero
in the original image, then the resultant pixel becomes black. For example, the upper left
of Fig. 23.2 is green. If red or blue is selected, then the upper left pixels become black, as
shown in Fig. 23.2 (b) and (d). Similarly, the upper right pixels of Fig. 23.2 are pure blue.
This means that these pixels become black if red or green is selected—shown in Fig. 23.2
(b) and (c). In most images, for example Fig. 23.3, each pixel is a mixture of all three colors.
After applying a color filter, the corresponding color stands out while the other two colors
are removed.
23.2.4 Inverting the Image Colors
The next method, BMP invert, inverts the color of each pixel. Fig. 23.4 shows the result
of this effect.
// bmpi nvert . c1
#in clude " bmpfunc . h"2
void BMP_inve r t ( B MP_Image * img )3
{4
int pxl ;5
for ( pxl = 0; pxl < ( img -> data_ size ) ; pxl ++)6
{7
img -> data [ pxl ] = 255 - ( img -> data [ pxl ]);8
}9
}10
390 Intermediate C Programming
23.2.5 Edge Detection
Detecting edges in an image is not easy because human brains have complex methods
using past experience and inferred knowledge. This book gives only a simple algorithm and
the results may be unsatisfactory in some ways. Part of the difficulty is that high level
features about objects must be known in order to determine where the edges are. That is
well beyond today’s state of the art. The problem looks simple because we, as humans, have
been seeing edges our entire lives. Commonly used computer edge detectors have no notion
of objects and attempt to detect edges from pixels. This chapter gives a very simple (but
still useful) method in the following steps:
1. Convert the RGB values to gray levels. This is the formula for converting an RGB
value to its corresponding gray level: 0.2989 × red + 0.5870 × green + 0.1140 × blue.
This formula is used because of the perceptual properties of the RGB color space.
2. Find the difference in the gray levels between two adjacent pixels.
3. If the difference is greater than a threshold value, then an edge has been detected.
Selecting the correct threshold depends on many factors. As shown in Fig. 23.5, if the
threshold is too high, then some edges are not detected. If the threshold is too low, then
the detection is sensitive to noise. In this example we set the threshold to 140. The code
listing below gives the function for detecting vertical edges using this simple setup.
// bmpedge .c1
#in clude " bmpfunc . h"2
#in clude < stdlib .h >3
s t a t i c i n t RGB2Gray ( char red , char green , char blue )4
{5
// this is a co m m only used formula6
double gray = 0.2989 * red + 0.5870 * green + 0.1140 * blue ;7
return ( in t ) gray ;8
}9
void B MP_edge ( BMP_Image * img , i n t thrshd )10
{11
// create a two - dimensi o n array for the gray level12
int width = img -> width ;13
int height = img -> height ;14
char * * two D Gray = malloc ( s i z e o f ( char *) * height ) ;15
int row ;16
int col ;17
for ( row = 0; row < height ; row ++)18
{19
twoDGray [ row ] = malloc ( s i z e o f ( char *) * width );20
}21
// convert RGB to gray22
int pxl = 0;23
for ( row = 0; row < height ; row ++)24
{25
for ( col = 0; col < width ; col ++)26
{27
twoDGray [ row ][ col ] = RGB2Gray ( img -> data [ pxl + 2] ,28
img -> data [ pxl + 1] ,29
img -> data [ pxl ]) ;30
pxl += 3;31
}32