From 5da13d4515b862d19282410d6e0766966acedc89 Mon Sep 17 00:00:00 2001 From: Moses_of_Egypt <29311834+MosesofEgypt@users.noreply.github.com> Date: Thu, 8 Aug 2019 14:35:22 -0400 Subject: [PATCH 1/6] Fixed incorrect parameter names in crop_pixel_data The parameters are upper bounds in that dimension, which wont necessarily be the new length of the dimension --- bitmap_io.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bitmap_io.py b/bitmap_io.py index 844206d..6b405a1 100644 --- a/bitmap_io.py +++ b/bitmap_io.py @@ -871,14 +871,14 @@ def make_array(typecode, item_ct, item_size=None, fill=0): def crop_pixel_data(pix, chan_ct, width, height, depth, - x0=0, new_width=-1, y0=0, new_height=-1, z0=0, new_depth=-1): - if new_width < 0: new_width = width - if new_height < 0: new_height = height - if new_depth < 0: new_depth = depth + x0=0, x1=-1, y0=0, y1=-1, z0=0, z1=-1): + if x1 < 0: x1 = width + if y1 < 0: y1 = height + if z1 < 0: z1 = depth new_pix = make_array( pix.typecode, - (new_width - x0) * (new_height - y0) * (new_depth - z0) * chan_ct, + (x1 - x0) * (y1 - y0) * (z1 - z0) * chan_ct, pix.itemsize) if len(pix) == 0: @@ -888,9 +888,9 @@ def crop_pixel_data(pix, chan_ct, width, height, depth, src_x_skip0, src_y_skip0, src_z_skip0 = max(x0, 0), max(y0, 0), max(z0, 0) - src_x_skip1 = max(width - src_x_skip0 - new_width, 0) - src_y_skip1 = max(height - src_y_skip0 - new_height, 0) - src_z_skip1 = max(depth - src_z_skip0 - new_depth, 0) + src_x_skip1 = max(width - src_x_skip0 - x1, 0) + src_y_skip1 = max(height - src_y_skip0 - y1, 0) + src_z_skip1 = max(depth - src_z_skip0 - z1, 0) x_stride = width - src_x_skip0 - src_x_skip1 y_stride = height - src_y_skip0 - src_y_skip1 @@ -901,15 +901,15 @@ def crop_pixel_data(pix, chan_ct, width, height, depth, dst_x_skip0, dst_y_skip0, dst_z_skip0 = max(-x0, 0), max(-y0, 0), max(-z0, 0) - dst_x_skip1 = max(new_width - dst_x_skip0 - x_stride, 0) - dst_y_skip1 = max(new_height - dst_y_skip0 - y_stride, 0) + dst_x_skip1 = max(x1 - dst_x_skip0 - x_stride, 0) + dst_y_skip1 = max(y1 - dst_y_skip0 - y_stride, 0) - src_z_skip0 *= width * height * pixel_width + src_z_skip0 *= width * pixel_width * height src_y_skip0 *= width * pixel_width src_y_skip1 *= width * pixel_width - dst_z_skip0 *= new_width * new_height * pixel_width - dst_y_skip0 *= new_width * pixel_width - dst_y_skip1 *= new_width * pixel_width + dst_z_skip0 *= x1 * pixel_width * y1 + dst_y_skip0 *= x1 * pixel_width + dst_y_skip1 *= x1 * pixel_width src_x_skip0 *= pixel_width dst_x_skip0 *= pixel_width From d9e6f0a85f1dbc7bc445b6b639ab5bcc8fe7c914 Mon Sep 17 00:00:00 2001 From: Moses_of_Egypt <29311834+MosesofEgypt@users.noreply.github.com> Date: Sat, 31 Aug 2019 03:37:04 -0400 Subject: [PATCH 2/6] Commented out debug code Fixed bug with test file not being named properly for reopening during test Added function for calculating channel order based on channel masks Added function for getting channel mapping to swap one channel order to match a different channel order Added function for swapping dds channels around. Annoyingly complicated Fix to dds loading where channels are now swapped to expected order if the order they are stored in the dds files != C_ORDER_BGRA --- arby.py | 4 +- bitmap_io.py | 83 +++++++++++++++++- test.py | 2 +- ...sc_A8R8G8B8.dds => disc_A8R8G8B8_tex0.dds} | Bin 4 files changed, 82 insertions(+), 7 deletions(-) rename test_files/{disc_A8R8G8B8.dds => disc_A8R8G8B8_tex0.dds} (100%) diff --git a/arby.py b/arby.py index 2bfdb9e..bdb98dd 100644 --- a/arby.py +++ b/arby.py @@ -1528,8 +1528,8 @@ def pack_all(self): p_height = self.get_target_packed_height(orig_h, m) p_depth = self.get_target_packed_depth(orig_d, m) if p_width != w or p_height != h or p_depth != d: - print("CROPPING FROM %sx%sx%s TO %sx%sx%s" % ( - w, h, d , p_width, p_height, p_depth)) + #print("CROPPING FROM %sx%sx%s TO %sx%sx%s" % ( + # w, h, d , p_width, p_height, p_depth)) pix = bitmap_io.crop_pixel_data( pix, (1 if self.is_palettized(i) else self.unpacked_channel_count), diff --git a/bitmap_io.py b/bitmap_io.py index 6b405a1..058be6c 100644 --- a/bitmap_io.py +++ b/bitmap_io.py @@ -30,6 +30,70 @@ ab = None +def get_channel_order_by_masks(a_mask=0, r_mask=0, g_mask=0, b_mask=0): + # shift the masks right until they're all the same scale + a_shift = r_shift = g_shift = b_shift = 0 + while a_mask and not(a_mask&1): + a_mask = a_mask >> 1 + a_shift += 1 + + while r_mask and not(r_mask&1): + r_mask = r_mask >> 1 + r_shift += 1 + + while g_mask and not(g_mask&1): + g_mask = g_mask >> 1 + g_shift += 1 + + while b_mask and not(b_mask&1): + b_mask = b_mask >> 1 + b_shift += 1 + + src_order_map = {} + if a_mask: src_order_map[a_shift] = 'a' + if r_mask: src_order_map[r_shift] = 'r' + if g_mask: src_order_map[g_shift] = 'g' + if b_mask: src_order_map[b_shift] = 'b' + return "".join(src_order_map[k] for k in sorted(src_order_map)) + + +def get_dds_channel_map(a_mask=0, r_mask=0, g_mask=0, b_mask=0, + dst_order=C_ORDER_BGRA): + src_order = get_channel_order_by_masks(a_mask, r_mask, g_mask, b_mask) + channel_map = get_channel_swap_mapping(src_order, dst_order) + new_order = "".join(("bgra"[i] if i in range(4) else "x") + for i in channel_map[::-1]) + return get_channel_swap_mapping(C_ORDER_ARGB, new_order) + + +def get_channel_swap_mapping(src_order, dst_order=C_ORDER_ARGB): + '''Takes a source channel order string and a destination channel + order string and returns a 4 item tuple that maps the source + channels to the destination order. + Valid src channel strings contain any arrangement of 'argb'. + The same appliesfor dst channel strings, but 'x' can also be used + to signify a channel is to be made blank(dropped from the source). + ''' + src_order = src_order.lower() + dst_order = dst_order.lower() + assert set(src_order).issubset("argb"), ( + "Source channel order must contain only the characters 'argbARGB'. " + "'%s' is an invalid channel order." % src_order + ) + assert set(dst_order).issubset("argbx"), ( + "Source channel order must contain only the characters 'argbxARGBX'. " + "'%s' is an invalid channel order." % dst_order + ) + channel_map = [] + for c in dst_order: + if c in src_order: + channel_map.append(src_order.index(c)) + else: + channel_map.append(-1) + + return tuple(channel_map) + + def load_from_dds_file(convertor, input_path, ext, **kwargs): """Loads a DDS file into the convertor.""" dds_file = dds_def.build(filepath="%s.%s" % (input_path, ext)) @@ -120,15 +184,20 @@ def load_from_dds_file(convertor, input_path, ext, **kwargs): chan_ct = ab.CHANNEL_COUNTS[fmt] channel_map = None if not fmt_flags.four_cc and chan_ct > 2: - channel_map = (fmt_head.a_bitmask, fmt_head.r_bitmask, - fmt_head.g_bitmask, fmt_head.b_bitmask)[: chan_ct] + # swap channels so everything is ARGB + # NOTE: This is extremely confusing and carefully calibrated + # to work with ARGB and RGB channels. DO NOT TOUCH + channel_map = get_dds_channel_map( + fmt_head.a_bitmask, fmt_head.r_bitmask, + fmt_head.g_bitmask, fmt_head.b_bitmask, + C_ORDER_BGRA)[: chan_ct] + tex_info = {"width": head.width, "height": head.height, "depth": max(head.depth, 1), "texture_type": typ, "filepath": dds_file.filepath, "format": fmt, "mipmap_count": mipmap_count, - "sub_bitmap_count": sub_bitmap_count, - "channel_mapping": channel_map} + "sub_bitmap_count": sub_bitmap_count} temp = [] #loop over each mipmap and cube face @@ -146,8 +215,14 @@ def load_from_dds_file(convertor, input_path, ext, **kwargs): for sb in range(sub_bitmap_count): tex_block[m*sub_bitmap_count + sb] = temp[ sb*(mipmap_count + 1) + m] + convertor.load_new_texture(texture_block=tex_block, texture_info=tex_info) + + if channel_map: + convertor.load_new_conversion_settings( + channel_mapping=channel_map) + convertor.convert_texture() except: print(format_exc()) diff --git a/test.py b/test.py index 7506089..891a475 100644 --- a/test.py +++ b/test.py @@ -42,7 +42,7 @@ def convert_chain(last_fmt, formats, **kwargs): try: bitmap_test.load_from_file( - input_path=curr_dir + "\\test_files\\disc_%s.dds" % last_fmt) + input_path=curr_dir + "\\test_files\\disc_%s_tex0.dds" % last_fmt) bitmap_test.load_new_conversion_settings( target_format=fmt, color_key_transparency=ck_trans, **kw) start = time.time() diff --git a/test_files/disc_A8R8G8B8.dds b/test_files/disc_A8R8G8B8_tex0.dds similarity index 100% rename from test_files/disc_A8R8G8B8.dds rename to test_files/disc_A8R8G8B8_tex0.dds From 4d445196e5b0d9688bf45adf20f98da54451e718 Mon Sep 17 00:00:00 2001 From: Moses_of_Egypt <29311834+MosesofEgypt@users.noreply.github.com> Date: Sun, 1 Sep 2019 01:51:43 -0400 Subject: [PATCH 3/6] Moved a comment to where it actually applies --- bitmap_io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bitmap_io.py b/bitmap_io.py index 058be6c..96b3fea 100644 --- a/bitmap_io.py +++ b/bitmap_io.py @@ -59,6 +59,8 @@ def get_channel_order_by_masks(a_mask=0, r_mask=0, g_mask=0, b_mask=0): def get_dds_channel_map(a_mask=0, r_mask=0, g_mask=0, b_mask=0, dst_order=C_ORDER_BGRA): + # NOTE: This is extremely confusing and carefully calibrated + # to work with ARGB and RGB channels. DO NOT TOUCH src_order = get_channel_order_by_masks(a_mask, r_mask, g_mask, b_mask) channel_map = get_channel_swap_mapping(src_order, dst_order) new_order = "".join(("bgra"[i] if i in range(4) else "x") @@ -185,8 +187,6 @@ def load_from_dds_file(convertor, input_path, ext, **kwargs): channel_map = None if not fmt_flags.four_cc and chan_ct > 2: # swap channels so everything is ARGB - # NOTE: This is extremely confusing and carefully calibrated - # to work with ARGB and RGB channels. DO NOT TOUCH channel_map = get_dds_channel_map( fmt_head.a_bitmask, fmt_head.r_bitmask, fmt_head.g_bitmask, fmt_head.b_bitmask, From 893549e839fb9919bfa208d9ca1af102455e1d53 Mon Sep 17 00:00:00 2001 From: MosesofEgypt Date: Sun, 1 Sep 2019 02:52:11 -0400 Subject: [PATCH 4/6] Update and rename .hgignore to .gitignore --- .gitignore | 10 ++++++++++ .hgignore | 11 ----------- 2 files changed, 10 insertions(+), 11 deletions(-) create mode 100644 .gitignore delete mode 100644 .hgignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7467be7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +**__pycache__/ +v7.1.lnk +tests/ +**/v15/ +**Release/ +Debug/ +test_files/bitmaps/ +**.db +**.suo +**.pyd diff --git a/.hgignore b/.hgignore deleted file mode 100644 index 3f8326c..0000000 --- a/.hgignore +++ /dev/null @@ -1,11 +0,0 @@ -syntax: glob -*__pycache__/* -v7.1.lnk -tests/ -*/v15/* -*Release/* -Debug/* -test_files/bitmaps/ -*.db -*.suo -*.pyd From 901138eb29c335c2cf7413668e5ea5d43753c156 Mon Sep 17 00:00:00 2001 From: Moses_of_Egypt Date: Tue, 3 Sep 2019 01:06:38 -0400 Subject: [PATCH 5/6] updated gitignore again --- .gitignore | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 7467be7..41f1282 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ -**__pycache__/ +__pycache__/ v7.1.lnk tests/ -**/v15/ -**Release/ +.vs/ +Release/ Debug/ -test_files/bitmaps/ -**.db -**.suo -**.pyd +*.db +*.suo +*.pyd From 3150d456dec3d9e54d233f5fc1d8e146c1219681 Mon Sep 17 00:00:00 2001 From: Moses_of_Egypt Date: Thu, 5 Sep 2019 14:55:06 -0400 Subject: [PATCH 6/6] Version bump --- __init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__init__.py b/__init__.py index 6b8bf1f..e558be8 100644 --- a/__init__.py +++ b/__init__.py @@ -3,8 +3,8 @@ # ############## __author__ = "Devin Bobadilla" # YYYY.MM.DD -__date__ = "2019.07.05" -__version__ = (1, 0, 2) +__date__ = "2019.09.05" +__version__ = (1, 0, 3) from arbytmap import constants from arbytmap.arby import *