Skip to content
This repository has been archived by the owner on Feb 12, 2018. It is now read-only.

Commit

Permalink
avereshchagin: Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
avereshchagin committed Dec 7, 2012
1 parent bf928fd commit 9db5242
Show file tree
Hide file tree
Showing 8 changed files with 471 additions and 0 deletions.
3 changes: 3 additions & 0 deletions avereshchagin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.pyc
.DS_Store
.idea
40 changes: 40 additions & 0 deletions avereshchagin/colors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
__author__ = 'Aleksandr Vereshchagin'

class AbstractColorModel:

def getRGB(self, color):
pass

def getYCbCr(self, color):
pass

class RgbColorModel(AbstractColorModel):

def getRGB(self, color):
return color

def getYCbCr(self, color):
r, g, b = color
y = 0.299 * r + 0.587 * g + 0.114 * b
cb = 128 - 0.168736 * r - 0.331264 * g + 0.5 * b
cr = 128 + 0.5 * r - 0.418688 * g - 0.081312 * b
return y, cr, cb

class YCbCrColorModel(AbstractColorModel):

def getRGB(self, color):
y, cr, cb = color
r = int(y + 1.402 * (cr - 128))
g = int(y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128))
b = int(y + 1.772 * (cb - 128))
if r < 0: r = 0
if r > 255: r = 255
if g < 0: g = 0
if g > 255: g = 255
if b < 0: b = 0
if b > 255: b = 255
return r, g, b

def getYCbCr(self, color):
return color

Binary file added avereshchagin/data/image.bmp
Binary file not shown.
2 changes: 2 additions & 0 deletions avereshchagin/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__author__ = 'Aleksandr Vereshchagin'

199 changes: 199 additions & 0 deletions avereshchagin/image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import sys
import numpy as np

__author__ = 'Aleksandr Vereshchagin'

import struct

def align(x, a):
return (((x - 1) // a) + 1) * a

class UnsupportedFileFormatError(Exception):
pass

HEADER_FORMAT = '<2sIHHIIIIHHIIIIII'

class BMPImage:

__signature = 'BM'
__size = 0
__offset = 54
__headerSize = 40
__width = 0
__height = 0
__planes = 1
__bpp = 24
__compression = 0
__sizeOfData = 0
__horizontalRes = 2835
__verticalRes = 2835
__rawData = None

def __loadBmpHeader(self, file):
header = file.read(struct.calcsize(HEADER_FORMAT))
(self.__signature, self.__size, ignored, ignored, self.__offset, self.__headerSize,
self.__width, self.__height, self.__planes, self.__bpp, self.__compression,
self.__sizeOfData, self.__horizontalRes, self.__verticalRes, ignored, ignored) =\
struct.unpack(HEADER_FORMAT, header)
if (self.__signature, self.__planes, self.__bpp, self.__compression) != ('BM', 1, 24, 0):
raise UnsupportedFileFormatError
# print 'Size of data: ' + str(self.__sizeOfData)

def __loadBmpData(self, file):
file.seek(self.__offset)
self.__rawData = []
for j in xrange(0, self.__height):
line = file.read(align(self.__width * 3, 4))
for i in xrange(0, self.__width * 3, 3):
self.__rawData.append(struct.unpack_from('<BBB', line, i))

def load(self, filename):
f = sys.stdin
if filename and isinstance(filename, str):
f = open(filename, 'rb')
with f as file:
self.__loadBmpHeader(file)
self.__loadBmpData(file)

def __writeHeader(self, file):
ignored = 0
header = (
self.__signature, self.__size, ignored, ignored, self.__offset, self.__headerSize,
self.__width, self.__height, self.__planes, self.__bpp, self.__compression,
self.__sizeOfData, self.__horizontalRes, self.__verticalRes, ignored, ignored
)
rawHeader = struct.pack(HEADER_FORMAT, *header)
file.write(rawHeader)

def __writeBmpData(self, file):
padding = align(self.__width * 3, 4) - self.__width * 3
print 'Padding: ' + str(padding)
counter = 0
for v in self.__rawData:
r, g, b = v
file.write(struct.pack('<BBB', r, g, b))
counter += 1
if counter == self.__width:
counter = 0
for i in xrange(0, padding):
file.write(struct.pack('<B', 0))

def save(self, filename):
with open(filename, 'wb') as file:
self.__writeHeader(file)
self.__writeBmpData(file)

def getDimensions(self):
return self.__width, self.__height

def setDimensions(self, width, height):
self.__width = width
self.__height = height
self.__sizeOfData = width * height * 3

def getRawData(self):
return self.__rawData

def setRawData(self, newData):
self.__rawData = newData

class CustomizableImage:

__width = 0
__height = 0

# (originalBlockSize, packedBlockSize, numberOfBlocks)
__yDescription = None
__cbDescription = None
__crDescription = None

__yData = None
__cbData = None
__crData = None

def __readHeader(self, file):
self.__width, self.__height = struct.unpack('<II', file.read(struct.calcsize('<II')))
self.__yDescription = struct.unpack('<HHH', file.read(struct.calcsize('<HHH')))
self.__cbDescription = struct.unpack('<HHH', file.read(struct.calcsize('<HHH')))
self.__crDescription = struct.unpack('<HHH', file.read(struct.calcsize('<HHH')))

def __readBlocks(self, file, description):
blocks = []
originalBlockSize = description[0]
packedBlockSize = description[1]
numberOfBlocks = description[2]
blockLength = packedBlockSize * packedBlockSize
pattern = '<' + 'h' * blockLength
for i in xrange(0, numberOfBlocks):
data = struct.unpack(pattern, file.read(struct.calcsize(pattern)))
block = np.matrix(np.zeros((originalBlockSize, originalBlockSize)))
block[0:packedBlockSize, 0:packedBlockSize] = np.matrix(data).reshape(packedBlockSize, packedBlockSize)
blocks.append(block)
return blocks

@staticmethod
def load(filename):
f = sys.stdin
if filename and isinstance(filename, str):
f = open(filename, 'rb')
with f as file:
image = CustomizableImage()
image.__readHeader(file)
if image.__yDescription[2] > 0:
image.__yData = image.__readBlocks(file, image.__yDescription)
if image.__cbDescription[2] > 0:
image.__cbData = image.__readBlocks(file, image.__cbDescription)
if image.__crDescription[2] > 0:
image.__crData = image.__readBlocks(file, image.__crDescription)
return image

def getYData(self):
return self.__yData

def getCbData(self):
return self.__cbData

def getCrData(self):
return self.__crData

def getDimensions(self):
return self.__width, self.__height

def setDimensions(self, width, height):
self.__width = width
self.__height = height

def setDescriptions(self, yDescription, cbDescription, crDescription):
self.__yDescription = yDescription
self.__cbDescription = cbDescription
self.__crDescription = crDescription

def setData(self, yData, cbData, crData):
yPackedBlockSize = self.__yDescription[1]
self.__yData = map(lambda x: x[0:yPackedBlockSize, 0:yPackedBlockSize], yData)
cbPackedBlockSize = self.__cbDescription[1]
self.__cbData = map(lambda x: x[0:cbPackedBlockSize, 0:cbPackedBlockSize], cbData)
crPackedBlockSize = self.__crDescription[1]
self.__crData = map(lambda x: x[0:crPackedBlockSize, 0:crPackedBlockSize], crData)

def __writeHeader(self, file):
file.write(struct.pack('<II', self.__width, self.__height))
file.write(struct.pack('<HHH', *self.__yDescription))
file.write(struct.pack('<HHH', *self.__cbDescription))
file.write(struct.pack('<HHH', *self.__crDescription))

def __writeBlocks(self, file, blocks):
for block in blocks:
data = np.array(block).reshape(-1).tolist()
file.write(struct.pack('<' + 'h' * len(data), *data))

def save(self, filename):
with open(filename, 'wb') as file:
self.__writeHeader(file)
if self.__yData:
self.__writeBlocks(file, self.__yData)
if self.__cbData:
self.__writeBlocks(file, self.__cbData)
if self.__crData:
self.__writeBlocks(file, self.__crData)

36 changes: 36 additions & 0 deletions avereshchagin/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import getopt
import sys
from task import Task

__author__ = 'Aleksandr Vereshchagin'

def usage():
print 'This is usage'

def processArgs(optlist, inputs, task):
if len(inputs) > 0:
task.withInput(inputs[0])
for opt, arg in optlist:
if opt in ('-c', '--compress'):
task.withAction('compress')
elif opt in ('-x', '--extract'):
task.withAction('extract')
elif opt in ('-o', '--output'):
task.withOutput(arg)
else:
print 'Unsupported option'

def main():
task = Task()
try:
optlist, args = getopt.getopt(sys.argv[1:], 'cxo:',
['compress', 'extract', 'output='])
processArgs(optlist, args, task)
except getopt.GetoptError as e:
print str(e)
usage()
return
task.run()

if __name__ == '__main__':
main()
Loading

0 comments on commit 9db5242

Please sign in to comment.