Skip to content

Commit

Permalink
Merge commit 'deepakjois/master'
Browse files Browse the repository at this point in the history
* commit 'deepakjois/master':
  Adding support for calculating JPG dimensions
  Adding image_height and image_width functions

Conflicts:
	lib/compass/sass_extensions/functions.rb
  • Loading branch information
chriseppstein committed Feb 22, 2010
2 parents 0c593e2 + a075a10 commit bae616e
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/compass/sass_extensions/functions.rb
@@ -1,7 +1,7 @@
module Compass::SassExtensions::Functions
end

%w(selectors enumerate urls display inline_image gradient_support font_files).each do |func|
%w(selectors enumerate urls display inline_image image_size gradient_support font_files).each do |func|
require "compass/sass_extensions/functions/#{func}"
end

Expand All @@ -11,6 +11,7 @@ module Sass::Script::Functions
include Compass::SassExtensions::Functions::Urls
include Compass::SassExtensions::Functions::Display
include Compass::SassExtensions::Functions::InlineImage
include Compass::SassExtensions::Functions::ImageSize
include Compass::SassExtensions::Functions::GradientSupport::Functions
include Compass::SassExtensions::Functions::FontFiles
end
Expand Down
99 changes: 99 additions & 0 deletions lib/compass/sass_extensions/functions/image_size.rb
@@ -0,0 +1,99 @@
module Compass::SassExtensions::Functions::ImageSize
def image_width(image_file)
image_path = real_path(image_file)
width = ImageProperties.new(image_path).size.first
Sass::Script::Number.new(width,["px"])
end

def image_height(image_file)
image_path = real_path(image_file)
height = ImageProperties.new(image_path).size.last
Sass::Script::Number.new(height, ["px"])
end

private
def real_path(image_file)
path = image_file.value
# Compute the real path to the image on the file stystem if the images_dir is set.
if Compass.configuration.images_dir
File.join(Compass.configuration.project_path, Compass.configuration.images_dir, path)
else
File.join(Compass.configuration.project_path, path)
end
end

class ImageProperties
def initialize(file)
@file = file
@file_type = File.extname(@file)[1..-1]
end

def size
@dimensions ||= send("get_size_for_#{@file_type}")
end

private
def get_size_for_png
IO.read(@file)[0x10..0x18].unpack('NN')
end

def get_size_for_gif
size = IO.read(@file)[6..10].unpack('SS')
size.inspect
end

def get_size_for_bmp
d = IO.read(@file)[14..28]
d[0] == 40 ? d[4..-1].unpack('LL') : d[4..8].unpack('SS')
end

def get_size_for_jpg
get_size_for_jpeg
end

def get_size_for_jpeg
jpeg = JPEG.new(@file)
[jpeg.width, jpeg.height]
end
end

class JPEG
attr_reader :width, :height, :bits

def initialize(file)
if file.kind_of? IO
examine(file)
else
File.open(file, 'rb') { |io| examine(io) }
end
end

private
def examine(io)
raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI

class << io
def readint; (readchar << 8) + readchar; end
def readframe; read(readint - 2); end
def readsof; [readint, readchar, readint, readint, readchar]; end
def next
c = readchar while c != 0xFF
c = readchar while c == 0xFF
c
end
end

while marker = io.next
case marker
when 0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF # SOF markers
length, @bits, @height, @width, components = io.readsof
raise 'malformed JPEG' unless length == 8 + components * 3
when 0xD9, 0xDA: break # EOI, SOS
when 0xFE: @comment = io.readframe # COM
when 0xE1: io.readframe # APP1, contains EXIF tag
else io.readframe # ignore frame
end
end
end
end
end

0 comments on commit bae616e

Please sign in to comment.