Exemple #1
0
    def _get_coeff(self):
        dct_array1 = create_array(0.0, 8, 8)
        dct_array2 = create_array(0.0, 8, 8)
        dct_array3 = create_array(0, 64)

        coeff = []
        for r in range(min(self.jpeg_obj.block_height)):
            for c in range(min(self.jpeg_obj.block_width)):
                xpos = c * 8
                ypos = r * 8
                for comp in range(self.jpeg_obj.comp_num):
                    indata = self.jpeg_obj.components[comp]
                    maxa = self.image_height / 2 * self.jpeg_obj.vsamp_factor[
                        comp] - 1
                    maxb = self.image_width / 2 * self.jpeg_obj.hsamp_factor[
                        comp] - 1

                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            ia = ypos * self.jpeg_obj.vsamp_factor[comp] + i * 8
                            ib = xpos * self.jpeg_obj.hsamp_factor[comp] + j * 8

                            for a in range(8):
                                for b in range(8):
                                    dct_array1[a][b] = indata[min(
                                        ia + a, maxa)][min(ib + b, maxb)]

                            dct_array2 = self.dct.forward_dct(dct_array1)
                            dct_array3 = self.dct.quantize_block(
                                dct_array2, self.jpeg_obj.qtable_number[comp])
                            coeff.extend(dct_array3[:64])
        return coeff
Exemple #2
0
    def __init__(self, quality):
        self.N = 8
        self.QUALITY = 80
        self.quantum = create_array(0, 2, self.N * self.N)
        self.divisors = create_array(0, 2, self.N * self.N)

        self.init_matrix(quality)
    def get_ycc_array(self):
        max_hsamp_factor = max(self.hsamp_factor)
        max_vsamp_factor = max(self.vsamp_factor)

        for i in range(self.comp_num):
            self.comp_width[i] = int(math.ceil(self.image_width / 8.0) * 8)
            self.comp_width[i] = self.comp_width[i] / max_hsamp_factor * self.hsamp_factor[i]
            self.block_width[i] = int(math.ceil(self.comp_width[i] / 8.0))

            self.comp_height[i] = int(math.ceil(self.image_height / 8.0) * 8)
            self.comp_height[i] = self.comp_height[i] / max_vsamp_factor * self.vsamp_factor[i]
            self.block_height[i] = int(math.ceil(self.comp_height[i] / 8.0))

        values = self.pixels
        Y  = create_array(0, self.comp_height[0], self.comp_width[0])
        Cb = create_array(0, self.comp_height[0], self.comp_width[0])
        Cr = create_array(0, self.comp_height[0], self.comp_width[0])

        for y in range(self.image_height):
            for x in range(self.image_width):
                r, g, b = values[x, y]
                Y[y][x]  =  0.299   * r + 0.587   * g + 0.114   * b
                Cb[y][x] = -0.16874 * r - 0.33126 * g + 0.5     * b + 128
                Cr[y][x] =  0.5     * r - 0.41869 * g - 0.08131 * b + 128

        self.components = [Y, self.down_sample(Cb, 1), self.down_sample(Cr, 2)]
    def __init__(self, quality):
        self.N = 8
        self.QUALITY = 80
        self.quantum  = create_array(0, 2, self.N * self.N)
        self.divisors = create_array(0, 2, self.N * self.N)

        self.init_matrix(quality)
    def _get_coeff(self):
        dct_array1 = create_array(0.0, 8, 8)
        dct_array2 = create_array(0.0, 8, 8)
        dct_array3 = create_array(0, 64)

        coeff = []
        for r in range(min(self.jpeg_obj.block_height)):
            for c in range(min(self.jpeg_obj.block_width)):
                xpos = c * 8
                ypos = r * 8
                for comp in range(self.jpeg_obj.comp_num):
                    indata = self.jpeg_obj.components[comp]
                    maxa = self.image_height / 2 * self.jpeg_obj.vsamp_factor[comp] - 1
                    maxb = self.image_width / 2 * self.jpeg_obj.hsamp_factor[comp] - 1

                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            ia = ypos * self.jpeg_obj.vsamp_factor[comp] + i * 8
                            ib = xpos * self.jpeg_obj.hsamp_factor[comp] + j * 8

                            for a in range(8):
                                for b in range(8):
                                    dct_array1[a][b] = indata[min(ia+a, maxa)][min(ib+b, maxb)]

                            dct_array2 = self.dct.forward_dct(dct_array1)
                            dct_array3 = self.dct.quantize_block(dct_array2, 
                                    self.jpeg_obj.qtable_number[comp])
                            coeff.extend(dct_array3[:64])
        return coeff
Exemple #6
0
    def get_ycc_array(self):
        max_hsamp_factor = max(self.hsamp_factor)
        max_vsamp_factor = max(self.vsamp_factor)

        for i in range(self.comp_num):
            self.comp_width[i] = int(math.ceil(self.image_width / 8.0) * 8)
            self.comp_width[i] = self.comp_width[
                i] / max_hsamp_factor * self.hsamp_factor[i]
            self.block_width[i] = int(math.ceil(self.comp_width[i] / 8.0))

            self.comp_height[i] = int(math.ceil(self.image_height / 8.0) * 8)
            self.comp_height[i] = self.comp_height[
                i] / max_vsamp_factor * self.vsamp_factor[i]
            self.block_height[i] = int(math.ceil(self.comp_height[i] / 8.0))

        values = self.pixels
        Y = create_array(0, self.comp_height[0], self.comp_width[0])
        Cb = create_array(0, self.comp_height[0], self.comp_width[0])
        Cr = create_array(0, self.comp_height[0], self.comp_width[0])

        for y in range(self.image_height):
            for x in range(self.image_width):
                r, g, b = values[x, y]
                Y[y][x] = 0.299 * r + 0.587 * g + 0.114 * b
                Cb[y][x] = -0.16874 * r - 0.33126 * g + 0.5 * b + 128
                Cr[y][x] = 0.5 * r - 0.41869 * g - 0.08131 * b + 128

        self.components = [Y, self.down_sample(Cb, 1), self.down_sample(Cr, 2)]
    def __init__(self, image, comment):
        self.components   = create_array(None, self.comp_num)
        self.comp_width   = create_array(0, self.comp_num)
        self.comp_height  = create_array(0, self.comp_num)
        self.block_width  = create_array(0, self.comp_num)
        self.block_height = create_array(0, self.comp_num)

        self.comment = comment
        self.image_width, self.image_height = image.size
        self.pixels = image.load()

        self.get_ycc_array()
Exemple #8
0
    def __init__(self, image, comment):
        self.components = create_array(None, self.comp_num)
        self.comp_width = create_array(0, self.comp_num)
        self.comp_height = create_array(0, self.comp_num)
        self.block_width = create_array(0, self.comp_num)
        self.block_height = create_array(0, self.comp_num)

        self.comment = comment
        self.image_width, self.image_height = image.size
        self.pixels = image.load()

        self.get_ycc_array()
    def sof0(self):
        self.lf = self.get_int()
        self.p = self.get_byte()
        self.y = self.get_int()
        self.x = self.get_int()
        self.nf = self.get_byte()

        self.c = create_array(0, self.nf)
        self.h = create_array(0, self.nf)
        self.v = create_array(0, self.nf)
        self.t = create_array(0, self.nf)

        for lp in range(self.nf):
            self.c[lp] = self.get_byte()
            self.h[lp], self.v[lp] = self.get_double_four_bits()
            self.t[lp] = self.get_byte()
Exemple #10
0
    def sof0(self):
        self.lf = self.get_int()
        self.p = self.get_byte()
        self.y = self.get_int()
        self.x = self.get_int()
        self.nf = self.get_byte()

        self.c = create_array(0, self.nf)
        self.h = create_array(0, self.nf)
        self.v = create_array(0, self.nf)
        self.t = create_array(0, self.nf)

        for lp in range(self.nf):
            self.c[lp] = self.get_byte()
            self.h[lp], self.v[lp] = self.get_double_four_bits()
            self.t[lp] = self.get_byte()
    def init_huf(self):
        self.dc_matrix = create_array(0, 2, 12, 2)
        self.ac_matrix = create_array(0, 2, 255, 2)

        def cal(bits, val, matrix):
            p = 0
            code = 0
            for l in range(1, len(bits)):
                for i in range(bits[l]):
                    matrix[val[p]] = (code, l)
                    p += 1
                    code += 1
                code <<= 1
        
        cal(self.BITS_DC_LUMINANCE,   self.VAL_DC_LUMINANCE,   self.dc_matrix[0])
        cal(self.BITS_AC_LUMINANCE,   self.VAL_AC_LUMINANCE,   self.ac_matrix[0])
        cal(self.BITS_DC_CHROMINANCE, self.VAL_DC_CHROMINANCE, self.dc_matrix[1])
        cal(self.BITS_AC_CHROMINANCE, self.VAL_AC_CHROMINANCE, self.ac_matrix[1])
Exemple #12
0
    def init_huf(self):
        self.dc_matrix = create_array(0, 2, 12, 2)
        self.ac_matrix = create_array(0, 2, 255, 2)

        def cal(bits, val, matrix):
            p = 0
            code = 0
            for l in range(1, len(bits)):
                for i in range(bits[l]):
                    matrix[val[p]] = (code, l)
                    p += 1
                    code += 1
                code <<= 1

        cal(self.BITS_DC_LUMINANCE, self.VAL_DC_LUMINANCE, self.dc_matrix[0])
        cal(self.BITS_AC_LUMINANCE, self.VAL_AC_LUMINANCE, self.ac_matrix[0])
        cal(self.BITS_DC_CHROMINANCE, self.VAL_DC_CHROMINANCE,
            self.dc_matrix[1])
        cal(self.BITS_AC_CHROMINANCE, self.VAL_AC_CHROMINANCE,
            self.ac_matrix[1])
Exemple #13
0
    def __init__(self, data):
        self.huffval = create_array([], 4)
        self.valptr = create_array([], 4)
        self.mincode = create_array([], 4)
        self.maxcode = create_array([], 4)
        self.zz = create_array(0, 64)
        self.qnt = create_array(0, 4, 64)

        self.data = EmbedData(data)
        self.size = len(self.data)
        self.ri = 0

        while True:
            if self.get_byte() == 255:
                b = self.get_byte()
                if b == 192:
                    self.sof0()
                elif b == 196:
                    self.dht()
                elif b == 219:
                    self.dqt()
                elif b == 217 or b == 218:
                    break
                elif b in self.APP:
                    self.skip_variable()
                elif b == self.DRI:
                    self.dri()
    def __init__(self, data):
        self.huffval = create_array([], 4)
        self.valptr = create_array([], 4)
        self.mincode = create_array([], 4)
        self.maxcode = create_array([], 4)
        self.zz = create_array(0, 64)
        self.qnt = create_array(0, 4, 64)

        self.data = EmbedData(data)
        self.size = len(self.data)
        self.ri = 0

        while True:
            if self.get_byte() == 255:
                b = self.get_byte()
                if b == 192:
                    self.sof0()
                elif b == 196:
                    self.dht()
                elif b == 219:
                    self.dqt()
                elif b == 217 or b == 218:
                    break
                elif b in self.APP:
                    self.skip_variable()
                elif b == self.DRI:
                    self.dri()
Exemple #15
0
    def __init__(self, data, l):
        self.bits = create_array(0, 17)
        self.huffval = create_array(0, 256)
        self.huffcode = create_array(0, 257)
        self.huffsize = create_array(0, 257)
        self.ehufco = create_array(0, 257)
        self.ehufsi = create_array(0, 257)
        self.mincode = create_array(0, 17)
        self.maxcode = create_array(0, 18)
        self.valptr = create_array(0, 17)

        self.data = data
        self.ln = 19 + self.get_table_data()

        self.generate_size_table()
        self.generate_code_table()
        self.order_codes()
        self.decode_tables()
    def __init__(self, data, l):
        self.bits = create_array(0, 17)
        self.huffval = create_array(0, 256)
        self.huffcode = create_array(0, 257)
        self.huffsize = create_array(0, 257)
        self.ehufco = create_array(0, 257)
        self.ehufsi = create_array(0, 257)
        self.mincode = create_array(0, 17)
        self.maxcode = create_array(0, 18)
        self.valptr = create_array(0, 17)

        self.data = data
        self.ln = 19 + self.get_table_data()

        self.generate_size_table()
        self.generate_code_table()
        self.order_codes()
        self.decode_tables()
    def decode(self):
        pred = create_array(0, self.nf)
        self.CNT = 0
        self.ls = self.get_int()
        self.ns = self.get_byte()

        cs = create_array(0, self.ns)
        td = create_array(0, self.ns)
        ta = create_array(0, self.ns)
        for lp in range(self.ns):
            cs[lp] = self.get_byte()
            td[lp], ta[lp] = self.get_double_four_bits()

        self.ss = self.get_byte()
        self.se = self.get_byte()
        self.ah, self.al = self.get_double_four_bits()

        buff = create_array(0, 2 * 8 * 8 * self.get_block_count())
        pos, mcu_count = 0, 0

        while True:
            for n_comp in range(0, self.nf):
                for cnt in range(self.h[n_comp] * self.v[n_comp]):
                    self.hftbl = td[n_comp] * 2
                    tmp = self._internal_decode()
                    self.diff = self.receive(tmp)
                    self.zz[0] = pred[0] + self.extend(self.diff, tmp)
                    pred[n_comp] = self.zz[0]

                    self.hftbl = ta[n_comp] * 2 + 1
                    self.decode_ac_coefficients()

                    for lp in range(64):
                        buff[pos] = self.zz[lp]
                        pos += 1

            mcu_count += 1
            if mcu_count == self.ri:
                mcu_count = 0
                self.CNT = 0
                pred[n_comp] = create_array(0, self.nf)

                self.get_byte()
                tmp_b = self.get_byte()
                if tmp_b == EOI:
                    break

            if self.available() <= 2:
                if self.available() == 2:
                    self.get_byte()
                    if self.get_byte() != self.EOI:
                        logger.error("file does not end with EOI")
                else:
                    if self.available() == 1:
                        logger.error("last byte: %X" % self.get_byte())
                    logger.error("file does not end with EOI")
                break

        return buff[:pos]
Exemple #18
0
    def decode(self):
        pred = create_array(0, self.nf)
        self.CNT = 0
        self.ls = self.get_int()
        self.ns = self.get_byte()

        cs = create_array(0, self.ns)
        td = create_array(0, self.ns)
        ta = create_array(0, self.ns)
        for lp in range(self.ns):
            cs[lp] = self.get_byte()
            td[lp], ta[lp] = self.get_double_four_bits()

        self.ss = self.get_byte()
        self.se = self.get_byte()
        self.ah, self.al = self.get_double_four_bits()

        buff = create_array(0, 2 * 8 * 8 * self.get_block_count())
        pos, mcu_count = 0, 0

        while True:
            for n_comp in range(0, self.nf):
                for cnt in range(self.h[n_comp] * self.v[n_comp]):
                    self.hftbl = td[n_comp] * 2
                    tmp = self._internal_decode()
                    self.diff = self.receive(tmp)
                    self.zz[0] = pred[0] + self.extend(self.diff, tmp)
                    pred[n_comp] = self.zz[0]

                    self.hftbl = ta[n_comp] * 2 + 1
                    self.decode_ac_coefficients()

                    for lp in range(64):
                        buff[pos] = self.zz[lp]
                        pos += 1

            mcu_count += 1
            if mcu_count == self.ri:
                mcu_count = 0
                self.CNT = 0
                pred[n_comp] = create_array(0, self.nf)

                self.get_byte()
                tmp_b = self.get_byte()
                if tmp_b == EOI:
                    break

            if self.available() <= 2:
                if self.available() == 2:
                    self.get_byte()
                    if self.get_byte() != self.EOI:
                        logger.error('file does not end with EOI')
                else:
                    if self.available() == 1:
                        logger.error('last byte: %X' % self.get_byte())
                    logger.error('file does not end with EOI')
                break

        return buff[:pos]
    def forward_dct_extreme(self, indata):
        output = create_array(0.0, self.N, self.N)
        my_cos = lambda x: math.cos((2.0 * x + 1) * u * math.PI / 16)
        special = lambda x: 1.0 / math.sqrt(2) if x == 0 else 1.0
        range_8 = range(8)

        for v in range_8:
            for u in range_8:
                for x in range_8:
                    for y in range_8:
                        output[v][u] += indata[x][y] * my_cos(x) * my_cos(y)
                output[v][u] *= 0.25 * special(u) * special(v)

        return output
Exemple #20
0
    def forward_dct_extreme(self, indata):
        output = create_array(0.0, self.N, self.N)
        my_cos = lambda x: math.cos((2.0 * x + 1) * u * math.PI / 16)
        special = lambda x: 1.0 / math.sqrt(2) if x == 0 else 1.0
        range_8 = range(8)

        for v in range_8:
            for u in range_8:
                for x in range_8:
                    for y in range_8:
                        output[v][u] += indata[x][y] * my_cos(x) * my_cos(y)
                output[v][u] *= 0.25 * special(u) * special(v)

        return output
Exemple #21
0
    def create_array(self, ResourceAttr):
        #A scenario attribute is a piece of data associated
        #with a resource attribute.
        #[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

        return util.create_array(self.client, ResourceAttr)
    def write_compressed_data(self):
        tmp = 0

        last_dc_value = create_array(0, self.jpeg_obj.comp_num)
        zero_array = create_array(0, 64)
        width, height = 0, 0

        min_block_width = min(self.jpeg_obj.block_width)
        min_block_height = min(self.jpeg_obj.block_height)

        logger.info('DCT/quantisation starts')
        logger.info('%d x %d' % (self.image_width, self.image_height))

        coeff = self._get_coeff()
        coeff_count = len(coeff)

        logger.info('got %d DCT AC/DC coefficients' % coeff_count)
        _changed, _embedded, _examined, _expected, _one, _large, _thrown, _zero = 0, 0, 0, 0, 0, 0, 0, 0
        shuffled_index = 0
        for i, cc in enumerate(coeff):
            if i % 64 == 0:
                continue
            if cc == 1 or cc == -1:
                _one += 1
            elif cc == 0:
                _zero += 1

        _large = coeff_count - _zero - _one - coeff_count / 64
        _expected = _large + int(0.49 * _one)

        logger.info('one=%d' % _one)
        logger.info('large=%d' % _large)

        logger.info('expected capacity: %d bits' % _expected)
        logger.info('expected capacity with')
        for i in range(1, 8):
            n = (1 << i) - 1
            changed = _large - _large % (n + 1)
            changed = (changed + _one + _one / 2 - _one / (n + 1)) / (n + 1)

            usable = (_expected * i / n - _expected * i / n % n) / 8
            if usable == 0:
                break

            logger.info('%s code: %d bytes (efficiency: %d.%d bits per change)' % ('default' if i == 1 else '(1, %d, %d)' % (n, i), usable, usable * 8 / changed, usable * 80 / changed % 10))

        if self.embedded_data is not None:
            logger.info('permutation starts')
            random = F5Random(self.password)
            permutation = Permutation(coeff_count, random)

            next_bit_to_embed = 0
            byte_to_embed = len(self.embedded_data)
            available_bits_to_embed = 0

            logger.info('Embedding of %d bits (%d+4 bytes)' % (byte_to_embed * 8 + 32, byte_to_embed))

            if byte_to_embed > 0x007fffff:
                byte_to_embed = 0x007ffff

            for i in range(1, 8):
                self.n = (1 << i) - 1
                usable = (_expected * i / self.n - _expected * i / self.n % self.n) / 8
                if usable < byte_to_embed + 4:
                    break

            k = i - 1
            self.n = (1 << k) - 1

            if self.n == 0:
                logger.info('using default code, file will not fit')
                self.n = 1
            elif self.n == 1:
                logger.info('using default code')
            else:
                logger.info('using (1, %d, %d) code' % (self.n, k))

            byte_to_embed |= k << 24
            byte_to_embed ^= random.get_next_byte()
            byte_to_embed ^= random.get_next_byte() << 8
            byte_to_embed ^= random.get_next_byte() << 16
            byte_to_embed ^= random.get_next_byte() << 24

            next_bit_to_embed = byte_to_embed & 1
            byte_to_embed >>= 1
            available_bits_to_embed = 31
            _embedded += 1

            for i, shuffled_index in enumerate(permutation.shuffled):
                if shuffled_index % 64 == 0 or coeff[shuffled_index] == 0:
                    continue
                cc = coeff[shuffled_index]
                _examined += 1

                if cc > 0 and (cc & 1) != next_bit_to_embed:
                    coeff[shuffled_index] -= 1
                    _changed +=1
                elif cc < 0 and (cc & 1) == next_bit_to_embed:
                    coeff[shuffled_index] += 1
                    _changed += 1

                if coeff[shuffled_index] != 0:
                    if available_bits_to_embed == 0:
                        if self.n > 1 or not self.embedded_data.available():
                            break
                        byte_to_embed = self.embedded_data.read()
                        byte_to_embed ^= random.get_next_byte()
                        available_bits_to_embed = 8
                    next_bit_to_embed = byte_to_embed & 1
                    byte_to_embed >>= 1
                    available_bits_to_embed -= 1
                    _embedded += 1
                else:
                    _thrown += 1

            if self.n > 1:
                try:
                    is_last_byte = False
                    filtered_index = FilteredCollection(permutation.shuffled[i+1:], lambda index: index % 64 and coeff[index])
                    while not is_last_byte:
                        k_bits_to_embed = 0
                        for i in range(k):
                            if available_bits_to_embed == 0:
                                if not self.embedded_data.available():
                                    is_last_byte = True
                                    break
                                byte_to_embed = self.embedded_data.read()
                                byte_to_embed ^= random.get_next_byte()
                                available_bits_to_embed = 8
                            next_bit_to_embed = byte_to_embed & 1
                            byte_to_embed >>= 1
                            available_bits_to_embed -= 1
                            k_bits_to_embed |= next_bit_to_embed << i
                            _embedded += 1

                        code_word = filtered_index.offer(self.n)
                        while True:
                            vhash = 0
                            for i, index in enumerate(code_word):
                                if coeff[index] > 0:
                                    extracted_bit = coeff[index] & 1
                                else:
                                    extracted_bit = 1 - (coeff[index] & 1)
                                if extracted_bit == 1:
                                    vhash ^= i + 1
                            i = vhash ^ k_bits_to_embed
                            if not i:
                                break

                            i -= 1
                            coeff[code_word[i]] += 1 if coeff[code_word[i]] < 0 else -1
                            _changed += 1

                            if not coeff[code_word[i]]:
                                _thrown += 1
                                code_word[i:i+1] = []
                                code_word.extend(filtered_index.offer(1))
                            else:
                                break
                except FilteredCollection.ListNotEnough:
                    pass

            if _examined > 0:
                logger.info('%d coefficients examined' % _examined)
            if _changed > 0:
                logger.info('%d coefficients changed (efficiency: %d.%d bits per change' % (_changed, _embedded / _changed, _embedded * 10 / _changed % 10))
            logger.info('%d coefficients thrown (zeroed)' % _thrown)
            logger.info('%d bits (%d bytes) embedded' % (_embedded, _embedded / 8))

        logger.info('starting hufman encoding')
        shuffled_index = 0

        for r in range(min_block_height):
            for c in range(min_block_width):
                for comp in range(self.jpeg_obj.comp_num):
                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            dct_array3 = coeff[shuffled_index:shuffled_index+64]
                            self.huf.huffman_block_encoder(self.out, dct_array3, last_dc_value[comp],
                                    self.jpeg_obj.dctable_number[comp], self.jpeg_obj.actable_number[comp])
                            last_dc_value[comp] = dct_array3[0]
                            shuffled_index += 64
        
        self.huf.flush_buffer(self.out)
Exemple #23
0
    def write_compressed_data(self):
        last_dc_value = create_array(0, self.jpeg_obj.comp_num)
        zero_array = create_array(0, 64)
        width, height = 0, 0
        min_block_width = min(self.jpeg_obj.block_width)
        min_block_height = min(self.jpeg_obj.block_height)

        logger.info('DCT/quantisation starts')
        logger.info('%d x %d' % (self.image_width, self.image_height))

        coeff = self._get_coeff()  #量化后的系数,是整数
        coeff_count = len(coeff)

        #导出未处理的QDCT
        if self.hasais:
            filename = 'unpro_ais.json'
        else:
            filename = 'unpro.json'
        with open(filename, 'w') as f_unprocess:
            json.dump(coeff, f_unprocess)

        #AIS处理
        if self.hasais:
            size_secret = self.embedded_data.len
            ais = Ais(coeff, size_secret)  #coeff被修改
            ais.statistic()
            self.k_matrix = ais.fix()
            with open('aised.json', 'w') as f_aised:
                json.dump(coeff, f_aised)

        #嵌入——>再统计嵌入后的数据,决定是否继续做AIS处理
        logger.info('got %d DCT AC/DC coefficients' % coeff_count)
        _changed, _embedded, _examined, _expected, _one, _large, _thrown, _zero = 0, 0, 0, 0, 0, 0, 0, 0
        shuffled_index = 0
        for i, cc in enumerate(coeff):
            if i % 64 == 0:
                continue
            if cc == 1 or cc == -1:
                _one += 1
            elif cc == 0:
                _zero += 1

        _large = coeff_count - _zero - _one - coeff_count / 64  #有效系数的个数
        _expected = _large + int(0.49 * _one)  #预期容量,shrinkage效应无法确定

        logger.info('one=%d' % _one)
        logger.info('large=%d' % _large)
        logger.info('\nexpected capacity: %d bits\n' % _expected)
        logger.info('expected capacity with')

        for i in range(1, 8):
            n = (1 << i) - 1  #n=2^i-1
            changed = _large - _large % (n + 1)
            changed = (changed + _one + _one / 2 - _one / (n + 1)) / (n + 1)
            usable = (_expected * i / n - _expected * i / n % n) / 8
            if usable == 0:
                break

            logger.info(
                '%s code: %d bytes (efficiency: %d.%d bits per change)' %
                ('default' if i == 1 else '(1, %d, %d)' % (n, i), usable,
                 usable * 8 / changed, usable * 80 / changed % 10))

        #shuffles all coefficients using a permutation,使用排列对系数进行混洗
        if self.embedded_data is not None:
            logger.info('permutation starts')
            random = F5Random(self.password)
            permutation = Permutation(coeff_count, random)

            next_bit_to_embed = 0
            byte_to_embed = len(self.embedded_data)
            available_bits_to_embed = 0

            logger.info('Embedding of %d bits (%d+4 bytes)' %
                        (byte_to_embed * 8 + 32, byte_to_embed))

            if byte_to_embed > 0x007fffff:
                byte_to_embed = 0x007ffff

            for i in range(1, 8):
                self.n = (1 << i) - 1
                usable = (_expected * i / self.n -
                          _expected * i / self.n % self.n) / 8
                if usable < byte_to_embed + 4:
                    break

            #确定(1,n,k)
            if self.k_matrix < 0:
                k = i - 1
            else:
                k = self.k_matrix
            self.n = (1 << k) - 1

            if self.n == 0:
                logger.info('using default code, file will not fit')
                self.n = 1
            elif self.n == 1:
                logger.info('using default code')
            else:
                logger.info('using (1, %d, %d) code' % (self.n, k))

            byte_to_embed |= k << 24
            byte_to_embed ^= random.get_next_byte()
            byte_to_embed ^= random.get_next_byte() << 8
            byte_to_embed ^= random.get_next_byte() << 16
            byte_to_embed ^= random.get_next_byte() << 24

            next_bit_to_embed = byte_to_embed & 1
            byte_to_embed >>= 1
            available_bits_to_embed = 31
            _embedded += 1

            for i, shuffled_index in enumerate(permutation.shuffled):
                if shuffled_index % 64 == 0 or coeff[shuffled_index] == 0:
                    continue
                cc = coeff[shuffled_index]
                _examined += 1

                if cc > 0 and (cc & 1) != next_bit_to_embed:
                    coeff[shuffled_index] -= 1
                    _changed += 1
                elif cc < 0 and (cc & 1) == next_bit_to_embed:
                    coeff[shuffled_index] += 1
                    _changed += 1

                if coeff[shuffled_index] != 0:
                    if available_bits_to_embed == 0:
                        if self.n > 1 or not self.embedded_data.available():
                            break
                        byte_to_embed = self.embedded_data.read()
                        byte_to_embed ^= random.get_next_byte()
                        available_bits_to_embed = 8
                    next_bit_to_embed = byte_to_embed & 1
                    byte_to_embed >>= 1
                    available_bits_to_embed -= 1
                    _embedded += 1
                else:
                    _thrown += 1

            if self.n > 1:
                try:
                    is_last_byte = False
                    filtered_index = FilteredCollection(
                        permutation.shuffled[i + 1:],
                        lambda index: index % 64 and coeff[index])
                    while not is_last_byte:
                        k_bits_to_embed = 0
                        for i in range(k):
                            if available_bits_to_embed == 0:
                                if not self.embedded_data.available():
                                    is_last_byte = True
                                    break
                                byte_to_embed = self.embedded_data.read()
                                byte_to_embed ^= random.get_next_byte()
                                available_bits_to_embed = 8
                            next_bit_to_embed = byte_to_embed & 1
                            byte_to_embed >>= 1
                            available_bits_to_embed -= 1
                            k_bits_to_embed |= next_bit_to_embed << i
                            _embedded += 1

                        code_word = filtered_index.offer(self.n)
                        while True:
                            vhash = 0
                            for i, index in enumerate(code_word):
                                if coeff[index] > 0:
                                    extracted_bit = coeff[index] & 1
                                else:
                                    extracted_bit = 1 - (coeff[index] & 1)
                                if extracted_bit == 1:
                                    vhash ^= i + 1
                            i = vhash ^ k_bits_to_embed
                            if not i:
                                break

                            i -= 1
                            coeff[code_word[i]] += 1 if coeff[
                                code_word[i]] < 0 else -1
                            _changed += 1

                            if not coeff[code_word[i]]:
                                _thrown += 1
                                code_word[i:i + 1] = []
                                code_word.extend(filtered_index.offer(1))
                            else:
                                break
                except FilteredCollection.ListNotEnough:
                    pass

            if _examined > 0:
                logger.info('%d coefficients examined' % _examined)
            if _changed > 0:
                logger.info(
                    '%d coefficients changed (efficiency: %d.%d bits per change'
                    % (_changed, _embedded / _changed,
                       _embedded * 10 / _changed % 10))
            logger.info('%d coefficients thrown (zeroed)' % _thrown)
            logger.info('%d bits (%d bytes) embedded' %
                        (_embedded, _embedded / 8))

        #导出嵌入后的系数coeff
        if self.hasais:
            filename2 = 'embeded_ais.json'
        else:
            filename2 = 'embeded.json'
        with open(filename2, 'w') as f_embeded:
            json.dump(coeff, f_embeded)

        logger.info('starting hufman encoding')
        shuffled_index = 0

        for r in range(min_block_height):
            for c in range(min_block_width):
                for comp in range(self.jpeg_obj.comp_num):
                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            dct_array3 = coeff[shuffled_index:shuffled_index +
                                               64]
                            self.huf.huffman_block_encoder(
                                self.out, dct_array3, last_dc_value[comp],
                                self.jpeg_obj.dctable_number[comp],
                                self.jpeg_obj.actable_number[comp])
                            last_dc_value[comp] = dct_array3[0]
                            shuffled_index += 64

        self.huf.flush_buffer(self.out)
        logger.info('hufman encode end')
Exemple #24
0
    def forward_dct(self, indata):
        output = [[indata[i][j] - 128.0 for j in range(0, 8)]
                  for i in range(0, 8)]
        tmp = create_array(0, 14)

        for i in range(8):
            for j in range(4):
                tmp[j] = output[i][j] + output[i][7 - j]
                tmp[7 - j] = output[i][j] - output[i][7 - j]

            output[i][0] = tmp[0] + tmp[3] + (tmp[1] + tmp[2])
            output[i][4] = tmp[0] + tmp[3] - (tmp[1] + tmp[2])

            tmp[12] = tmp[1] - tmp[2]
            tmp[13] = tmp[0] - tmp[3]
            z1 = (tmp[12] + tmp[13]) * 0.707106781
            output[i][2] = tmp[13] + z1
            output[i][6] = tmp[13] - z1

            tmp[10] = tmp[4] + tmp[5]
            tmp[11] = tmp[5] + tmp[6]
            tmp[12] = tmp[6] + tmp[7]

            z5 = (tmp[10] - tmp[12]) * 0.382683433
            z2 = 0.541196100 * tmp[10] + z5
            z4 = 1.306562965 * tmp[12] + z5
            z3 = tmp[11] * 0.707106781

            z11 = tmp[7] + z3
            z13 = tmp[7] - z3

            output[i][5] = z13 + z2
            output[i][3] = z13 - z2
            output[i][1] = z11 + z4
            output[i][7] = z11 - z4

        for i in range(8):
            for j in range(4):
                tmp[j] = output[j][i] + output[7 - j][i]
                tmp[7 - j] = output[j][i] - output[7 - j][i]

            output[0][i] = tmp[0] + tmp[3] + (tmp[1] + tmp[2])
            output[4][i] = tmp[0] + tmp[3] - (tmp[1] + tmp[2])

            tmp[12] = tmp[1] - tmp[2]
            tmp[13] = tmp[0] - tmp[3]
            z1 = (tmp[12] + tmp[13]) * 0.707106781
            output[2][i] = tmp[13] + z1
            output[6][i] = tmp[13] - z1

            tmp[10] = tmp[4] + tmp[5]
            tmp[11] = tmp[5] + tmp[6]
            tmp[12] = tmp[6] + tmp[7]

            z5 = (tmp[10] - tmp[12]) * 0.382683433
            z2 = 0.541196100 * tmp[10] + z5
            z4 = 1.306562965 * tmp[12] + z5
            z3 = tmp[11] * 0.707106781

            z11 = tmp[7] + z3
            z13 = tmp[7] - z3

            output[5][i] = z13 + z2
            output[3][i] = z13 - z2
            output[1][i] = z11 + z4
            output[7][i] = z11 - z4

        return output
    def forward_dct(self, indata):
        output = [[indata[i][j] - 128.0 for j in range(0, 8)] for i in range(0, 8)]
        tmp = create_array(0, 14)

        for i in range(8):
            for j in range(4):
                tmp[j]   = output[i][j] + output[i][7-j]
                tmp[7-j] = output[i][j] - output[i][7-j]

            output[i][0] = tmp[0] + tmp[3] + (tmp[1] + tmp[2])
            output[i][4] = tmp[0] + tmp[3] - (tmp[1] + tmp[2])

            tmp[12] = tmp[1] - tmp[2]
            tmp[13] = tmp[0] - tmp[3]
            z1 = (tmp[12] + tmp[13]) * 0.707106781
            output[i][2] = tmp[13] + z1
            output[i][6] = tmp[13] - z1

            tmp[10] = tmp[4] + tmp[5]
            tmp[11] = tmp[5] + tmp[6]
            tmp[12] = tmp[6] + tmp[7]

            z5 = (tmp[10] - tmp[12]) * 0.382683433
            z2 = 0.541196100 * tmp[10] + z5
            z4 = 1.306562965 * tmp[12] + z5
            z3 = tmp[11] * 0.707106781

            z11 = tmp[7] + z3
            z13 = tmp[7] - z3

            output[i][5] = z13 + z2
            output[i][3] = z13 - z2
            output[i][1] = z11 + z4
            output[i][7] = z11 - z4

        for i in range(8):
            for j in range(4):
                tmp[j]   = output[j][i] + output[7-j][i]
                tmp[7-j] = output[j][i] - output[7-j][i]

            output[0][i] = tmp[0] + tmp[3] + (tmp[1] + tmp[2])
            output[4][i] = tmp[0] + tmp[3] - (tmp[1] + tmp[2])

            tmp[12] = tmp[1] - tmp[2]
            tmp[13] = tmp[0] - tmp[3]
            z1 = (tmp[12] + tmp[13]) * 0.707106781
            output[2][i] = tmp[13] + z1
            output[6][i] = tmp[13] - z1

            tmp[10] = tmp[4] + tmp[5]
            tmp[11] = tmp[5] + tmp[6]
            tmp[12] = tmp[6] + tmp[7]

            z5 = (tmp[10] - tmp[12]) * 0.382683433
            z2 = 0.541196100 * tmp[10] + z5
            z4 = 1.306562965 * tmp[12] + z5
            z3 = tmp[11] * 0.707106781

            z11 = tmp[7] + z3
            z13 = tmp[7] - z3

            output[5][i] = z13 + z2
            output[3][i] = z13 - z2
            output[1][i] = z11 + z4
            output[7][i] = z11 - z4

        return output
Exemple #26
0
    def create_array(self, ResourceAttr):
        #A scenario attribute is a piece of data associated
        #with a resource attribute.
        #[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

        return util.create_array(self.client, ResourceAttr)