(function () {
    function Pixelator(imageData) {
        if (!validateProps(imageData, Object, 'width', 'number', 'height', 'number', 'data', Uint8ClampedArray)) {
            throw new TypeError('The first argument passed into the Pixelator constructor was not a valid ImageData object.');
        }
        
        this.width = imageData.width;
        this.height = imageData.height;
        this.pixelCollection = new RGBAPixelCollection(imageData);
        this.rawImageData = imageData;
    }
    
    Pixelator.prototype.pixelate = function (sectionWidth, sectionHeight) {
        var sections = this.getAllSections(sectionWidth, sectionHeight),
            canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            i = sections.length;
        
        while (i--) {
            var section = sections[i],
                average = Pixelator.getAverageColor(section);
            
            ctx.fillStyle = 'rgba(' + average.r + ',' + average.g + ',' + average.b + ',' average.a + ')';
            ctx.fillRect(section.x, section.y, section.width, section.height);
        }
    };
    
    Pixelator.prototype.getAllSections = function (sectionWidth, sectionHeight) {
        
    };
    
    Pixelator.prototype.filters_ = [];
    
    function RGBAPixelCollection (imageData) {
        if (!validateProps(imageData, Object, 'width', 'number', 'height', 'number')) {
            throw new TypeError('The first argument passed into the RGBAPixelCollection constructor was not a valid ImageData object.');
        }
        
        this.width = imageData.width;
        this.height = imageData.height;
        this.pixels = [];
        
        var data = imageData.data;
        
        if (data instanceof Uint8ClampedArray) {
            this.raw = imageData;
            
            for (var i = 0; i < data.length; i+= 4) {
                this.pixels.push(new RGBAColor(data[i], data[i + 1], data[i + 2], data[i + 3], true));
            }
        } else {
            var size = this.width * this.height;
            
            for (var i = 0; i < size; i++) {
                this.pixels.push(new RGBAColor(0, 0, 0, 255, true));
            }
            
            this.raw = this.toSimpleImageData();
        }
    }
    
    RGBAPixelCollection.prototype.getIndicesInRect = function (startX, startY, rectWidth, rectHeight) {
        var indices = [],
            endX = startX + rectWidth - 1,
            endY = startY + rectHeight - 1,
            collectionWidth = this.width;
        
        for (var row = startY; row <= endY; row++) {
            for (var rowCell = startX; rowCell = endX; rowCell++) {
                indices.push(row * collectionWidth + rowCell);
            }
        }
        
        return indices;
    };
    
    RGBAPixelCollection.prototype.setPixelByIndex = function (index, color) {
        if (!(index in this.pixels)) {
            throw new RangeError('The index argument (' + JSON.stringify(index) + ') is not a valid index.');
        }
        
        if (!(color instanceof Object && 'r' in color && 'g' in color && 'b' in color && 'a' in color)) {
            throw new TypeError('The color argument (' + JSON.stringify(color) + ') is not a valid color.');
        }
        
        var pixel = this.pixels[index];
        
        pixel.r = color.r;
        pixel.g = color.g;
        pixel.b = color.b;
        pixel.a = color.a;
        
        return pixel;
    };
    
    /*
    RGBAPixelCollection.prototype.clone = function () {
        return new RGBAPixelCollection(this.raw);
    };
    */
    
    RGBAPixelCollection.prototype.toSimpleImageData = function () {
        var imageData = {width: this.width, height: this.height},
            pixels = this.pixels,
            data = new Uint8ClampedArray(this.width * this.height);
        
        for (var i = 0; i < pixels.length; i+= 4) {
            var currentPixel = pixels[i];
            
            data[i] = currentPixel.r;
            data[i + 1] = currentPixel.g;
            data[i + 2] = currentPixel.b;
            data[i + 3] = currentPixel.a;
        }
        
        imageData.data = data;
        
        return imageData;
    };
    
    /*
    RGBAPixelCollection.prototype.toImage = function () {
        var canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            
            image = document.createElement('img'),
            
            pixels = this.pixels,
            size = pixels.length,
            
            width = this.width,
            height = this.height;
        
        canvas.width = width;
        canvas.height = height;
        
        for (var i = 0; i < size; i++) {
            var pixel = pixels[i];
            
            ctx.fillStyle = 'rgba(' + pixel.r + ',' + pixel.g + ',' + pixel.b + ',' + pixel.a + ')';
            ctx.fillRect(i % width, Math.floor(i / width), 1, 1);
        }
        
        image.src = canvas.toDataURL();
        
        return image;
    };
    
    RGBAPixelCollection.prototype.toDataURL = function () {
        var canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            
            pixels = this.pixels,
            size = pixels.length,
            
            width = this.width,
            height = this.height;
        
        canvas.width = width;
        canvas.height = height;
        
        for (var i = 0; i < size; i++) {
            var pixel = pixels[i];
            
            ctx.fillStyle = 'rgba(' + pixel.r + ',' + pixel.g + ',' + pixel.b + ',' + pixel.a + ')';
            ctx.fillRect(i % width, Math.floor(i / width), 1, 1);
        }
        
        return canvas.toDataURL();
    };
    */
    
    function validateProps(obj, constructor) {
        if (!(obj instanceof Object) || typeof constructor !== 'function' || !(obj instanceof constructor)) {
            return false;
        }
        
        var numOfArgs = arguments.length;
        
        for (var i = 2; i < numOfArgs; i += 2) {
            var prop = obj[arguments[i]],
                propType = arguments[i + 1],
                propTypeType = typeof propType;
            
            if (
                (propTypeType === 'function' && !(prop instanceof propType)) ||
                (propTypeType === 'string' && typeof prop !== propType) ||
                (propTypeType !== 'function' && propTypeType !== 'string')
            ) {
                return false;
            }
        }
        
        return true;
    }
    
    function multiValueTypeCheck(type) {
        var typeType = typeof type,
            i = arguments.length;
        
        if (typeType === 'function') {
            while (--i) { // Skip first argument (which is the type argument).
                if (!(arguments[i] instanceof type)) {
                    return false;
                }
            }
        } else if (typeType === 'string') {
            while (--i) {
                if (typeof arguments[i] !== type) {
                    return false;
                }
            }
        } else return true;
    }
    
    function RGBAColor(red, green, blue, alpha, opt_skipValidation) {
        if (opt_skipValidation || !this.isValid.call({r: red, g: green, b: blue, a: alpha})) {
            throw new TypeError('Exactly four unsigned 8-bit integers must be provided as arguments to the RGBAColor constructor.');
        }
        
        this.r = red;
        this.g = green;
        this.b = blue;
        this.a = alpha;
    }
    
    RGBA.prototype = {
        r: 0,
        g: 0,
        b: 0,
        a: 255
    };
    
    RGBA.prototype.isValid = function () {
        function isUint8 (num) {
            return (
                num === parseInt(num, 10) &&
                num <= 255 &&
                num >= 0
            );
        }
        
        return (isUint8(this.r) && isUint8(this.g) && isUint8(this.b) && isUint8(this.a));
    };
    
    window['Pixelator'] = Pixelator;
})();

@@ -1219,24 +1219,163 @@
 ) %7B%0A        
+var rightEdgeSectionX = this.width - this.width %25 sectionWidth,%0A            bottomEdgeSectionY = this.Height - this.height %25 sectionHeight;
 %0A    %7D;%0A    

Update pixelator.js