Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Cool Fire
bmp-encode
Commits
28cfc4c4
Commit
28cfc4c4
authored
Dec 20, 2015
by
Cool Fire
Browse files
Initial commit of file.
parents
Changes
1
Hide whitespace changes
Inline
Side-by-side
bmpencode.rb
0 → 100755
View file @
28cfc4c4
#!/usr/bin/env ruby
require
'optparse'
# Option parsing
inputfile
=
''
outputfile
=
''
width
=
0
height
=
0
padding
=
0
decode
=
false
ARGV
.
options
do
|
opts
|
opts
.
separator
'When no filenames are provided STDIO is used'
opts
.
separator
'When no width is provided a the square root of the input size is used.'
opts
.
on
(
'-i'
,
'--input=filename'
,
'Read input from file'
)
{
|
val
|
inputfile
=
val
}
opts
.
on
(
'-o'
,
'--output=filename'
,
'Write output to file'
)
{
|
val
|
outputfile
=
val
}
opts
.
on
(
'-w'
,
'--width=value'
,
'Make image "value" pixels wide'
)
{
|
val
|
width
=
val
.
to_i
}
opts
.
on
(
'-p'
,
'--padding'
,
'Pad pixel rows with 0-bytes to ensure all data is in pixel values'
)
{
padding
=
1
}
opts
.
on
(
'-d'
,
'--decode'
,
'Decode bmp back to original file'
)
{
decode
=
true
}
opts
.
parse!
end
# Start reading input
data
=
''
output
=
''
if
(
inputfile
==
''
)
data
=
ARGF
.
read
else
data
=
IO
.
binread
(
inputfile
)
end
if
(
decode
)
# Decoding
# Read headers we care about
data
=
data
.
bytes
padsize
=
data
[
6
..
7
].
pack
(
'C*'
).
unpack
(
'S_'
)[
0
]
padding
=
data
[
8
..
9
].
pack
(
'C*'
).
unpack
(
'S_'
)[
0
]
width
=
data
[
18
..
21
].
pack
(
'C*'
).
unpack
(
'I'
)[
0
]
# Calculate end of data
dend
=
data
.
size
-
padsize
-
1
# Calculate row padding
rowpadsize
=
(
width
*
3
)
%
4
if
(
rowpadsize
>
0
)
rowpadsize
=
4
-
rowpadsize
end
# Decode
if
(
padding
==
1
&&
rowpadsize
!=
0
)
pc
=
0
data
[
54
..-
1
].
pack
(
'C*'
).
each_byte
{
|
b
|
pc
+=
1
if
(
pc
>
width
*
3
)
if
(
pc
==
(
width
*
3
)
+
rowpadsize
)
pc
=
0
end
next
else
output
.
concat
([
b
].
pack
(
'C*'
))
end
}
dend
=
-
1
-
padsize
output
=
output
.
bytes
[
0
..
dend
].
pack
(
'C*'
)
else
output
=
data
[
54
..
dend
].
pack
(
'C*'
)
end
else
# Encoding
# Add padding if needed
padsize
=
data
.
bytesize
%
4
if
(
padsize
>
0
)
padsize
=
4
-
padsize
end
data
=
data
.
concat
([
0x00
].
pack
(
'C*'
)
*
padsize
)
# Calculate image dimensions
if
(
width
==
0
)
width
=
Math
.
sqrt
(
data
.
bytesize
/
3
).
ceil
()
height
=
width
else
height
=
((
data
.
bytesize
/
3
)
/
width
.
to_f
).
ceil
()
end
# Calculate extra bytes required for row padding
rowpadsize
=
(
width
*
3
)
%
4
if
(
rowpadsize
>
0
)
rowpadsize
=
4
-
rowpadsize
end
totalrowpad
=
0
if
(
padding
==
1
)
totalrowpad
=
rowpadsize
*
height
end
# Construct BMP header
bfType
=
[
0x42
,
0x4D
]
# BMP specification type
bfSize
=
[
54
+
data
.
bytesize
+
totalrowpad
]
# File size
bfReserved1
=
[
padsize
]
# Reserved, always 0 [abused to store number of padding bytes added for alignment]
bfReserved2
=
[
padding
]
# Reserved, always 0 [abused to store if extra row padding was used]
bfOffBits
=
[
0x36
,
0x00
,
0x00
,
0x00
]
# Offset to start of image data
# Construct image header
biSize
=
[
0x28
,
0x00
,
0x00
,
0x00
]
# Image header size [always 40 bytes here]
biWidth
=
[
width
]
# Image width in px
biHeight
=
[
height
]
# Image height in px
biPlanes
=
[
0x01
,
0x00
]
# BMP planes [Always 1]
biBitCount
=
[
0x18
,
0x00
]
# Bits per pixel [Always 24 here]
biCompression
=
[
0x00
,
0x00
,
0x00
,
0x00
]
# Compression [Always no compression here]
biSizeImage
=
[
0x00
,
0x00
,
0x00
,
0x00
]
# Image size [May be 0 because no compression is used]
biXPelsPerMeter
=
[
0x13
,
0x0B
,
0x00
,
0x00
]
# Preferred resolution in pixels per meter
biYPelsPerMeter
=
[
0x13
,
0x0B
,
0x00
,
0x00
]
# Preferred resolution in pixels per meter
biClrUsed
=
[
0x00
,
0x00
,
0x00
,
0x00
]
# Number of Color Map entities used [unused here]
biClrImportant
=
[
0x00
,
0x00
,
0x00
,
0x00
]
# Number of signifcant colors [unused here]
# Print headers
output
.
concat
(
bfType
.
pack
(
'C*'
))
output
.
concat
(
bfSize
.
pack
(
'I'
))
output
.
concat
(
bfReserved1
.
pack
(
'S_'
))
output
.
concat
(
bfReserved2
.
pack
(
'S_'
))
output
.
concat
(
bfOffBits
.
pack
(
'C*'
))
output
.
concat
(
biSize
.
pack
(
'C*'
))
output
.
concat
(
biWidth
.
pack
(
'I'
))
output
.
concat
(
biHeight
.
pack
(
'I'
))
output
.
concat
(
biPlanes
.
pack
(
'C*'
))
output
.
concat
(
biBitCount
.
pack
(
'C*'
))
output
.
concat
(
biCompression
.
pack
(
'C*'
))
output
.
concat
(
biSizeImage
.
pack
(
'I'
))
output
.
concat
(
biXPelsPerMeter
.
pack
(
'C*'
))
output
.
concat
(
biYPelsPerMeter
.
pack
(
'C*'
))
output
.
concat
(
biClrUsed
.
pack
(
'C*'
))
output
.
concat
(
biClrImportant
.
pack
(
'C*'
))
# Print content
if
(
padding
==
1
)
pc
=
0
data
.
each_byte
{
|
b
|
pc
+=
1
output
.
concat
([
b
].
pack
(
'C*'
))
if
(
pc
==
width
*
3
)
output
.
concat
([
0x00
].
pack
(
'C*'
)
*
rowpadsize
)
pc
=
0
end
}
else
output
.
concat
(
data
)
end
end
# Write out results
if
(
outputfile
==
''
)
print
output
else
IO
.
binwrite
(
outputfile
,
output
)
end
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment