function renderImageToCanvas(img, blob, canvas, options, doSquash) {
        var iw = img.naturalWidth,
            ih = img.naturalHeight,
            width = options.width,
            height = options.height,
            ctx = canvas.getContext("2d"),
            promise = new qq.Promise(),
            modifiedDimensions;

        ctx.save();

        if (options.resize) {
            return renderImageToCanvasWithCustomResizer({
                blob: blob,
                canvas: canvas,
                image: img,
                imageHeight: ih,
                imageWidth: iw,
                orientation: options.orientation,
                resize: options.resize,
                targetHeight: height,
                targetWidth: width
            });
        }

        if (!qq.supportedFeatures.unlimitedScaledImageSize) {
            modifiedDimensions = maybeCalculateDownsampledDimensions({
                origWidth: width,
                origHeight: height
            });

            if (modifiedDimensions) {
                qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",
                    width, height, modifiedDimensions.newWidth, modifiedDimensions.newHeight),
                    "warn");

                width = modifiedDimensions.newWidth;
                height = modifiedDimensions.newHeight;
            }
        }

        transformCoordinate(canvas, width, height, options.orientation);

        // Fine Uploader specific: Save some CPU cycles if not using iOS
        // Assumption: This logic is only needed to overcome iOS image sampling issues
        if (qq.ios()) {
            (function() {
                if (detectSubsampling(img)) {
                    iw /= 2;
                    ih /= 2;
                }

                var d = 1024, // size of tiling canvas
                    tmpCanvas = document.createElement("canvas"),
                    vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1,
                    dw = Math.ceil(d * width / iw),
                    dh = Math.ceil(d * height / ih / vertSquashRatio),
                    sy = 0,
                    dy = 0,
                    tmpCtx, sx, dx;

                tmpCanvas.width = tmpCanvas.height = d;
                tmpCtx = tmpCanvas.getContext("2d");

                while (sy < ih) {
                    sx = 0;
                    dx = 0;
                    while (sx < iw) {
                        tmpCtx.clearRect(0, 0, d, d);
                        tmpCtx.drawImage(img, -sx, -sy);
                        ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);
                        sx += d;
                        dx += dw;
                    }
                    sy += d;
                    dy += dh;
                }
                ctx.restore();
                tmpCanvas = tmpCtx = null;
            }());
        }
        else {
            ctx.drawImage(img, 0, 0, width, height);
        }

        canvas.qqImageRendered && canvas.qqImageRendered();
        promise.success();

        return promise;
    }
Rendering image element (with resizing) into the canvas element