To get around images not divisable by 4, you need to check to make sure, that the pixel are not outside the pixmap.
Function round:Float(n:Float) Local r:Float = n Mod 2.0 If r >=.5 Return Ceil(n) Else Return Floor(n) EndIf End Function Function ditherfilter:timage(source:TImage, brush:TImage) Local sourcePixmap:TPixmap = LockImage(source) Local sourcePixmapPtr:Byte Ptr = PixmapPixelPtr(sourcePixmap, 0, 0) Local tmpPixmap:TPixmap = CopyPixmap(sourcePixmap) Local tmpPixmapPtr:Byte Ptr = PixmapPixelPtr(tmpPixmap,0,0) Local x:Int,y:Int Local w:Int = tmpPixmap.width Local h:Int = tmpPixmap.height Local extra_width:Float = w - (Floor(w / 4) * 4) Local extra_height:Float = h - (Floor(h / 4) * 4) For x = 0 To w - 1 Step 4' this is a 4 pixel jump thgouth the image For y = 0 To h - 1 Step 4 ' this is a 4 pixel jump thgouth the image ' set the component totals to be averaged upon completion Local total_red:Float = 0 Local total_green:Float = 0 Local total_blue:Float = 0 Local pixels_scanned:Float = 0 Local gray:Float = 0 Local subimage:Float = 0 'average the color of each 4x4 square For Local x2:Int = 0 To 3 If x+x2 < w Then For Local y2:Int = 0 To 3 If y+y2 < h Then ' get the color of each pixel of 16 Local red:Float = sourcePixmapPtr[(x + x2) * 4 + (y + y2) * 4 * w] Local green:Float = sourcePixmapPtr[(x + x2) * 4 + (y + y2) * 4 * w + 1] Local blue:Float = sourcePixmapPtr[(x + x2) * 4 + (y + y2) * 4 * w + 2] total_red:+red total_green:+green total_blue:+blue pixels_scanned:+1 End If Next End If Next 'draw the 4x4 fill total_red:/pixels_scanned total_green:/pixels_scanned total_blue:/pixels_scanned gray = (total_red + total_green + total_blue) / 3 For Local x2:Int = 0 To 3 If x+x2 < w Then For Local y2:Int = 0 To 3 If y+y2 < h Then subimage = round(gray / 255 * 16) Local brush:TPixmap = LockImage(brush, subimage, 0, 0) Local brushPixmapPtr:Byte Ptr = PixmapPixelPtr(brush, 0, 0) Local w2:Int = brush.width tmpPixmapPtr[(x + x2) * 4 + (y + y2) * 4 * w] = brushPixmapPTr[x2 * 4 + y2 * 4 * w2] tmpPixmapPtr[(x + x2) * 4 + (y + y2) * 4 * w + 1] = brushPixmapPTr[x2 * 4 + y2 * 4 * w2 + 1] tmpPixmapPtr[(x + x2) * 4 + (y + y2) * 4 * w + 2] = brushPixmapPTr[x2 * 4 + y2 * 4 * w2 + 2] 'alpha End If Next End If Next Next Next Local tmpImage:TImage = LoadImage(tmpPixmap) Return tmpImage End Function