code: def test_gray_semibyte_per_pixel(self):
      test_files = (
          (
              24.8,  # epsilon
              (  # group
                  "Tests/images/tiff_gray_2_4_bpp/hopper2.tif",
                  "Tests/images/tiff_gray_2_4_bpp/hopper2I.tif",
                  "Tests/images/tiff_gray_2_4_bpp/hopper2R.tif",
                  "Tests/images/tiff_gray_2_4_bpp/hopper2IR.tif",
              ),
          ),
          (
              7.3,  # epsilon
              (  # group
                  "Tests/images/tiff_gray_2_4_bpp/hopper4.tif",
                  "Tests/images/tiff_gray_2_4_bpp/hopper4I.tif",
                  "Tests/images/tiff_gray_2_4_bpp/hopper4R.tif",
                  "Tests/images/tiff_gray_2_4_bpp/hopper4IR.tif",
              ),
          ),
      )
      original = hopper("L")
      for epsilon, group in test_files:
          with Image.open(group[0]) as im:
              assert im.size == (128, 128)
              assert im.mode == "L"
              assert_image_similar(im, original, epsilon)
              for file in group[1:]:
                  with Image.open(file) as im2:
                      assert im2.size == (128, 128)
                      assert im2.mode == "L"
                      assert_image_equal(im, im2)
  
imports: import os
  from io import BytesIO
  import pytest
  from PIL import Image, ImageFile, TiffImagePlugin
  from PIL.TiffImagePlugin import RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION
  from .helper import assert_image_equal, assert_image_equal_tofile, assert_image_similar, assert_image_similar_tofile, hopper, is_pypy, is_win32
label_desc: Use image node_id 45 for calling the TestFileTiff obj's underlying member method code with example usage: obj.test_gray_semibyte_per_pixel() without return types