Edit

kc3-lang/angle/scripts/bmp_to_nv12.py

Branch :

  • Show log

    Commit

  • Author : Geoff Lang
    Date : 2019-05-06 13:15:35
    Hash : d7d42395
    Message : Format all of ANGLE's python code. BUG=angleproject:3421 Change-Id: I1d7282ac513c046de5d8ed87f7789290780d30a6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1595440 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>

  • scripts/bmp_to_nv12.py
  • #!/usr/bin/python2
    #
    # Copyright 2016 The ANGLE Project Authors. All rights reserved.
    # Use of this source code is governed by a BSD-style license that can be
    # found in the LICENSE file.
    #
    # bmp_to_nv12.py:
    #   Script to convert a simple BMP file to an NV12 format. Used to create
    #   test images for the NV12 texture stream end to end tests
    
    import sys
    import struct
    
    if len(sys.argv) != 4:
        print("Usage: bmp_to_nv12.py input output prefix")
        exit(0)
    
    bmp_file = open(sys.argv[1], "rb")
    
    magic = bmp_file.read(2)
    if (magic != "BM"):
        print("Invalid BMP magic")
        exit(1)
    
    file_size, = struct.unpack("I", bmp_file.read(4))
    
    # eat reserved bytes
    bmp_file.read(4)
    
    offset, = struct.unpack("I", bmp_file.read(4))
    
    headersize, = struct.unpack("I", bmp_file.read(4))
    width, = struct.unpack("i", bmp_file.read(4))
    height, = struct.unpack("i", bmp_file.read(4))
    planes, = struct.unpack("H", bmp_file.read(2))
    bpp, = struct.unpack("H", bmp_file.read(2))
    compression, = struct.unpack("i", bmp_file.read(4))
    image_size, = struct.unpack("i", bmp_file.read(4))
    
    if (bpp != 24 or compression != 0):
        print("Unsupported BMP file")
        bmp_file.close()
        exit(1)
    
    bmp_file.seek(offset, 0)
    pixels = bmp_file.read(width * height * 3)
    bmp_file.close()
    
    # convert to YUV 4:4:4
    converted_pixels = bytearray(pixels)
    for i in range(0, width * height):
        R, = struct.unpack("B", pixels[i * 3 + 2])
        G, = struct.unpack("B", pixels[i * 3 + 1])
        B, = struct.unpack("B", pixels[i * 3])
        converted_pixels[i * 3] = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16
        converted_pixels[i * 3 + 1] = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128
        converted_pixels[i * 3 + 2] = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128
    
    # downsample to packed UV buffer
    uv_buffer = bytearray(width * height / 2)
    for i in range(0, width * height / 2, 2):
        U1 = converted_pixels[((((i / width) * 2) * width) + (i % width)) * 3 + 1]
        U2 = converted_pixels[((((i / width) * 2) * width) + width + (i % width)) * 3 + 1]
        V1 = converted_pixels[((((i / width) * 2) * width) + (i % width)) * 3 + 2]
        V2 = converted_pixels[((((i / width) * 2) * width) + width + (i % width)) * 3 + 2]
        uv_buffer[i] = (U1 + U2) / 2
        uv_buffer[i + 1] = (V1 + V2) / 2
    
    # extract the Y buffer
    y_buffer = bytearray(width * height)
    for i in range(0, width * height):
        y_buffer[i] = converted_pixels[i * 3]
    
    # write out the file as a C header
    nv12_file = open(sys.argv[2], "w")
    nv12_file.write("// Automatically generated from " + sys.argv[1] + "\n")
    nv12_file.write("static const size_t " + sys.argv[3] + "_width = " + str(width) + ";\n")
    nv12_file.write("static const size_t " + sys.argv[3] + "_height = " + str(height) + ";\n")
    nv12_file.write("static const unsigned char " + sys.argv[3] + "_data[] = \n{")
    for i in range(0, width * height):
        if (i % 16) == 0:
            nv12_file.write("\n    ")
        nv12_file.write(str(y_buffer[i]) + ",")
    for i in range(0, width * height / 2):
        if (i % 16) == 0:
            nv12_file.write("\n    ")
        nv12_file.write(str(uv_buffer[i]) + ",")
    nv12_file.write("\n};")
    nv12_file.close()