Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c3267f5

Browse files
authored
Revert "[Web] Fix BMP encoder (#29448)"
This reverts commit 15d5a23.
1 parent 8f272d9 commit c3267f5

File tree

2 files changed

+44
-203
lines changed

2 files changed

+44
-203
lines changed

lib/web_ui/lib/src/ui/painting.dart

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -500,83 +500,71 @@ Future<void> _decodeImageFromListAsync(Uint8List list, ImageDecoderCallback call
500500
final FrameInfo frameInfo = await codec.getNextFrame();
501501
callback(frameInfo.image);
502502
}
503-
504-
// Encodes the input pixels into a BMP file that supports transparency.
505-
//
506-
// The `pixels` should be the scanlined raw pixels, 4 bytes per pixel, from left
507-
// to right, then from top to down. The order of the 4 bytes of pixels is
508-
// decided by `format`.
509503
Future<Codec> _createBmp(
510504
Uint8List pixels,
511505
int width,
512506
int height,
513507
int rowBytes,
514508
PixelFormat format,
515509
) {
516-
late bool swapRedBlue;
517-
switch (format) {
518-
case PixelFormat.bgra8888:
519-
swapRedBlue = true;
520-
break;
521-
case PixelFormat.rgba8888:
522-
swapRedBlue = false;
523-
break;
524-
}
525-
526510
// See https://en.wikipedia.org/wiki/BMP_file_format for format examples.
527-
// The header is in the 108-byte BITMAPV4HEADER format, or as called by
528-
// Chromium, WindowsV4. Do not use the 56-byte or 52-byte Adobe formats, since
529-
// they're not supported.
530-
const int dibSize = 0x6C /* 108: BITMAPV4HEADER */;
531-
const int headerSize = dibSize + 0x0E;
532-
final int bufferSize = headerSize + (width * height * 4);
511+
final int bufferSize = 0x36 + (width * height * 4);
533512
final ByteData bmpData = ByteData(bufferSize);
534513
// 'BM' header
535-
bmpData.setUint16(0x00, 0x424D, Endian.big);
514+
bmpData.setUint8(0x00, 0x42);
515+
bmpData.setUint8(0x01, 0x4D);
536516
// Size of data
537517
bmpData.setUint32(0x02, bufferSize, Endian.little);
538518
// Offset where pixel array begins
539-
bmpData.setUint32(0x0A, headerSize, Endian.little);
519+
bmpData.setUint32(0x0A, 0x36, Endian.little);
540520
// Bytes in DIB header
541-
bmpData.setUint32(0x0E, dibSize, Endian.little);
542-
// Width
521+
bmpData.setUint32(0x0E, 0x28, Endian.little);
522+
// width
543523
bmpData.setUint32(0x12, width, Endian.little);
544-
// Height
524+
// height
545525
bmpData.setUint32(0x16, height, Endian.little);
546-
// Color panes (always 1)
526+
// Color panes
547527
bmpData.setUint16(0x1A, 0x01, Endian.little);
548-
// bpp: 32
549-
bmpData.setUint16(0x1C, 32, Endian.little);
550-
// Compression method is BITFIELDS to enable bit fields
551-
bmpData.setUint32(0x1E, 3, Endian.little);
552-
// Raw bitmap data size
528+
// 32 bpp
529+
bmpData.setUint16(0x1C, 0x20, Endian.little);
530+
// no compression
531+
bmpData.setUint32(0x1E, 0x00, Endian.little);
532+
// raw bitmap data size
553533
bmpData.setUint32(0x22, width * height, Endian.little);
554-
// Print DPI width
534+
// print DPI width
555535
bmpData.setUint32(0x26, width, Endian.little);
556-
// Print DPI height
536+
// print DPI height
557537
bmpData.setUint32(0x2A, height, Endian.little);
558-
// Colors in the palette
538+
// colors in the palette
559539
bmpData.setUint32(0x2E, 0x00, Endian.little);
560-
// Important colors
540+
// important colors
561541
bmpData.setUint32(0x32, 0x00, Endian.little);
562-
// Bitmask R
563-
bmpData.setUint32(0x36, swapRedBlue ? 0x00FF0000 : 0x000000FF, Endian.little);
564-
// Bitmask G
565-
bmpData.setUint32(0x3A, 0x0000FF00, Endian.little);
566-
// Bitmask B
567-
bmpData.setUint32(0x3E, swapRedBlue ? 0x000000FF : 0x00FF0000, Endian.little);
568-
// Bitmask A
569-
bmpData.setUint32(0x42, 0xFF000000, Endian.little);
570-
571-
int destinationByte = headerSize;
572-
final Uint32List combinedPixels = Uint32List.sublistView(pixels);
573-
// BMP is scanlined from bottom to top. Rearrange here.
574-
for (int rowCount = height - 1; rowCount >= 0; rowCount -= 1) {
575-
int sourcePixel = rowCount * rowBytes;
576-
for (int colCount = 0; colCount < width; colCount += 1) {
577-
bmpData.setUint32(destinationByte, combinedPixels[sourcePixel], Endian.little);
578-
destinationByte += 4;
579-
sourcePixel += 1;
542+
543+
544+
int pixelDestinationIndex = 0;
545+
late bool swapRedBlue;
546+
switch (format) {
547+
case PixelFormat.bgra8888:
548+
swapRedBlue = true;
549+
break;
550+
case PixelFormat.rgba8888:
551+
swapRedBlue = false;
552+
break;
553+
}
554+
for (int pixelSourceIndex = 0; pixelSourceIndex < pixels.length; pixelSourceIndex += 4) {
555+
final int r = swapRedBlue ? pixels[pixelSourceIndex + 2] : pixels[pixelSourceIndex];
556+
final int b = swapRedBlue ? pixels[pixelSourceIndex] : pixels[pixelSourceIndex + 2];
557+
final int g = pixels[pixelSourceIndex + 1];
558+
final int a = pixels[pixelSourceIndex + 3];
559+
560+
// Set the pixel past the header data.
561+
bmpData.setUint8(pixelDestinationIndex + 0x36, r);
562+
bmpData.setUint8(pixelDestinationIndex + 0x37, g);
563+
bmpData.setUint8(pixelDestinationIndex + 0x38, b);
564+
bmpData.setUint8(pixelDestinationIndex + 0x39, a);
565+
pixelDestinationIndex += 4;
566+
if (rowBytes != width && pixelSourceIndex % width == 0) {
567+
pixelSourceIndex += rowBytes - width;
580568
}
581569
}
582570

@@ -815,3 +803,4 @@ class FragmentProgram {
815803
required Float32List floatUniforms,
816804
}) => throw UnsupportedError('FragmentProgram is not supported for the CanvasKit or HTML renderers.');
817805
}
806+

lib/web_ui/test/html/image_test.dart

Lines changed: 0 additions & 148 deletions
This file was deleted.

0 commit comments

Comments
 (0)