=========================================================== Color conversion out[i] = (unsigned char)(0.299*R+0.587*G+0.114*B) Geometric transform: Image boundaries: I treat the center of a pixel as integers. Therefore the bounding box of an image is not on integer locations. For example, for an image of (W, H), the four corners are defined as double offset=0.5; vertex[0]=0-offset; vertex[4]=0-offset;; vertex[8]=1; vertex[1]=0-offset; vertex[5]=H-offset; vertex[9]=1; vertex[2]=W-offset; vertex[6]=H-offset; vertex[10]=1; vertex[3]=W-offset; vertex[7]=0-offset; vertex[11]=1; Notice the 0.5 offset. Then I compute the transformed positions of the bounding box, and find xmin, xmax, ymin, ymax the new image's width and height are defined as newW=(int)(xmax-xmin); newH=(int)(ymax-ymin); For each pixel in the output image, its coordinate for inverse mapping is computed as (x+xmin, y+ymin) When I do bilinear interpolation, I will only compute a value if all of a pixel's four neighbors in the input image are defined, i.e., no out of bound pixels. Otherwise, I output a black.