diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index 288a7299b..f1c725e50 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -14,10 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* globals assert, assertWellFormed, ColorSpace, Dict, Encodings, error,
-           ErrorFont, Font, FONT_IDENTITY_MATRIX, fontCharsToUnicode, FontFlags,
-           ImageKind, info, isArray, isCmd, isDict, isEOF, isName, isNum,
-           isStream, isString, JpegStream, Lexer, Metrics, Name, Parser,
+/* globals assert, assertWellFormed, ColorSpace, DecodeStream, Dict, Encodings,
+           error, ErrorFont, Font, FONT_IDENTITY_MATRIX, fontCharsToUnicode,
+           FontFlags, ImageKind, info, isArray, isCmd, isDict, isEOF, isName,
+           isNum, isStream, isString, JpegStream, Lexer, Metrics, Name, Parser,
            Pattern, PDFImage, PDFJS, serifFonts, stdFontMap, symbolsFonts,
            getTilingPatternIR, warn, Util, Promise, LegacyPromise,
            RefSetCache, isRef, TextRenderingMode, CMapFactory, OPS,
@@ -146,10 +146,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
         var bitStrideLength = (width + 7) >> 3;
         var imgArray = image.getBytes(bitStrideLength * height);
         var decode = dict.get('Decode', 'D');
+        var canTransfer = image instanceof DecodeStream;
         var inverseDecode = !!decode && decode[0] > 0;
 
         operatorList.addOp(OPS.paintImageMaskXObject,
-          [PDFImage.createMask(imgArray, width, height, inverseDecode)]
+          [PDFImage.createMask(imgArray, width, height, canTransfer,
+                               inverseDecode)]
         );
         return;
       }
diff --git a/src/core/image.js b/src/core/image.js
index 25d47fa16..bea15909a 100644
--- a/src/core/image.js
+++ b/src/core/image.js
@@ -209,19 +209,25 @@ var PDFImage = (function PDFImageClosure() {
     return temp;
   };
 
-  PDFImage.createMask = function PDFImage_createMask(imgArray, width, height,
-                                                     inverseDecode) {
-    // Copy imgArray into a typed array (inverting if necessary) so it can be
-    // transferred to the main thread.
+  PDFImage.createMask =
+      function PDFImage_createMask(imgArray, width, height, canTransfer,
+                                   inverseDecode) {
+    // If imgArray came from a DecodeStream, we're safe to transfer it.
+    // Otherwise, copy it.
     var actualLength = imgArray.byteLength;
-    var data = new Uint8Array(actualLength);
+    var data;
+    if (canTransfer) {
+      data = imgArray;
+    } else {
+      data = new Uint8Array(actualLength);
+      data.set(imgArray);
+    }
+    // Invert if necessary. It's safe to modify the array -- whether it's the
+    // original or a copy, we're about to transfer it anyway, so nothing else
+    // in this thread can be relying on its contents.
     if (inverseDecode) {
       for (var i = 0; i < actualLength; i++) {
-        data[i] = ~imgArray[i];
-      }
-    } else {
-      for (var i = 0; i < actualLength; i++) {
-        data[i] = imgArray[i];
+        data[i] = ~data[i];
       }
     }