Skip to content

Commit

Permalink
Merge pull request #2 from MosesofEgypt/develop
Browse files Browse the repository at this point in the history
Merge Develop. Version bumped from (1, 0, 2) to (1, 0, 3)

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.
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
Commented out debug code.
  • Loading branch information
MosesofEgypt authored Sep 5, 2019
2 parents b243d68 + 3150d45 commit ce4e9bc
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 34 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
__pycache__/
v7.1.lnk
tests/
.vs/
Release/
Debug/
*.db
*.suo
*.pyd
11 changes: 0 additions & 11 deletions .hgignore

This file was deleted.

4 changes: 2 additions & 2 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
4 changes: 2 additions & 2 deletions arby.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
111 changes: 93 additions & 18 deletions bitmap_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,72 @@
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):
# 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")
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))
Expand Down Expand Up @@ -120,15 +186,18 @@ 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
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
Expand All @@ -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())

Expand Down Expand Up @@ -871,14 +946,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:
Expand All @@ -888,9 +963,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
Expand All @@ -901,15 +976,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
Expand Down
2 changes: 1 addition & 1 deletion test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
File renamed without changes.

0 comments on commit ce4e9bc

Please sign in to comment.