1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
#===========================================================================#
# caTools - R library #
# Copyright (C) 2005 Jarek Tuszynski #
# Distributed under GNU General Public License version 3 #
#===========================================================================#
write.gif = function(image, filename, col="gray",
scale=c("smart", "never", "always"), transparent=NULL,
comment=NULL, delay=0, flip=FALSE, interlace=FALSE)
{
if (!is.character(filename)) stop("write.gif: 'filename' has to be a string")
if (length(filename)>1) filename = paste(filename, collapse = "") # combine characters into a string
#======================================
# cast 'image' into a proper dimentions
#======================================
dm = dim(image)
if (is.null(dm)) stop("write.gif: input 'x' has to be an matrix or 3D array")
if (length(dm)<=2) { # this is a 2D matrix or smaller
image = as.matrix(image) # cast to 2D matrix
if (flip) x = image[,dm[2]:1]
else x = t(image)
} else { # 3D data cube or bigger
dim(image) = c(dm[1], dm[2], prod(dm)/(dm[1]*dm[2])) # cast to 3D
if (flip) x = image[,dm[2]:1,]
else x = aperm(image, c(2,1,3))
}
image = 0 # release memory
dm = dim(x) # save dimentions and ...
x = as.vector(x) # convert to 1D vector
#=================================
# scale x into a proper range
#=================================
scale = match.arg(scale)
if (!is.null(transparent))
if ((transparent<0) || (transparent>255))
stop("write.gif:'transparent' has to be an integer between 0 and 255")
mask = !is.finite(x)
xx = 0
mColor = 255
if (any(mask)) { # some non-finite numbers were found
if (is.null(transparent)) mColor = 254
xx = x # save original x
x = x[!mask] # remove non-finite numbers
}
minx = min(x)
maxx = max(x)
d = mColor/(maxx-minx)
if (scale=="never") {
if ((minx<0) || (maxx>mColor))
warning("write.gif: 'x' is not in proper range and 'scale' is set to 'never',",
" clipping 'x' to proper range ")
if (minx<0 ) x[x<0 ] = 0
if (maxx>mColor) x[x>mColor] = mColor
} else
if (scale=="always") {
if ((minx>=0) && (maxx<=1))
x = mColor*x # doubles between [0 and 1] -> scale them
else
x = (x-minx)*d # numbers outside allowed range -> scale them
} else
if (scale=="smart") {
if ((minx<0) || (maxx>mColor)) {
x = (x-minx)*d # numbers outside allowed range -> scale them
} else if ((minx>=0) && (maxx<=1)) {
if (any(x!=as.integer(x))) x = mColor*x # doubles between [0 and 1] -> scale them
}
}
maxx = max(x)
if (length(xx)>1) { # some non-finite numbers were found
if (is.null(transparent)) transparent = maxx+1
xx[ mask] = transparent
xx[!mask] = x
x = xx
}
if (is.null(transparent)) transparent = -1
x = as.integer(round(x))
#=================================
# format color palette
#=================================
n = maxx+1
if (is.character(col) && length(col)==1) {
if (col %in% c("grey", "gray")) col = gray(0:n/n)
if (col=="jet")
col = colorRampPalette(c("#00007F", "blue", "#007FFF", "cyan", "#7FFF7F",
"yellow", "#FF7F00", "red", "#7F0000")) # define "jet" palette
}
if (length(col)==1) { # if not a vector than maybe it is a palette function
FUN = match.fun(col) # make sure it is a function not a string with function name
col = FUN(n)
}
crgb = col2rgb(col)
Palette = as.integer(c(256^(2:0) %*% crgb)) # convert to internal int format
nColor = length(Palette)
if (nColor<maxx)
stop("write.gif: not enough colors in color palette 'col'. Has ",nColor,
" need at least ", maxx)
if (nColor<256) Palette = c(Palette, rep(0,256-nColor)) # pad it
# format and cast other input variables into proper format
param = as.integer(c( dm[2], dm[1], prod(dm)/(dm[1]*dm[2]), nColor, transparent, delay, interlace, 0 ))
if (is.null(comment)) comment = as.character("")
else comment = as.character(comment)
# call C++ function
.C("imwritegif", filename, x, Palette, param, comment,
NAOK=FALSE, PACKAGE="caTools")
if (param[7]<0) stop("write.gif: cannot open the output file (connection)")
invisible(NULL)
}
#==============================================================================
read.gif = function(filename, frame=0, flip=FALSE, verbose=FALSE)
{
if (!is.character(filename)) stop("write.gif: 'filename' has to be a string")
if (length(filename)>1) filename = paste(filename, collapse = "") # combine characters into a string
isURL = length(grep("^http://", filename)) |
length(grep("^ftp://", filename)) |
length(grep("^file://", filename))
if(isURL) {
tf <- tempfile()
download.file(filename, tf, mode='wb', quiet=TRUE)
filename = tf
}
x = .Call("imreadgif", filename, as.integer(frame), as.integer(verbose),
PACKAGE="caTools")
comt = as.character(attr(x, 'comm'))
if (isURL) file.remove(filename)
nRow = x[1]
nCol = x[2]
nBand = x[3]
tran = x[4]
success = x[5]
nPixel = nRow*nCol*nBand
stats = -success
if (stats>=6) {
warning("write.gif: file '", filename,
"' contains multiple color-maps. Use 'frame' > 0.")
stats = stats-6
}
if (nPixel==0) {
switch (stats,
stop("write.gif: cannot open the input file: ", filename, call.=FALSE),
stop("write.gif: input file '", filename, "' is not a GIF file", call.=FALSE),
stop("write.gif: unexpected end of file: ", filename, call.=FALSE),
stop("write.gif: syntax error in file: ", filename, call.=FALSE) )
} else {
switch (stats, , ,
warning("write.gif: unexpected end of file: ", filename, call.=FALSE),
warning("write.gif: syntax error in file: ", filename, call.=FALSE),
warning("write.gif: file '", filename,
"' contains multiple images (frames) of uneven length. Use 'frame' > 0." , call.=FALSE))
}
Palette = x[ 10:265 ]
x = x[-(1:265)] # delete non image data
if (nBand>1) { # 3D data cubes
dim(x) = c(nCol, nRow, nBand)
if (flip) x = x[,ncol(x):1,]
else x = aperm(x, c(2,1,3))
} else { # this is a matrix
dim(x) = c(nCol, nRow)
if (flip) x = x[,ncol(x):1]
else x = t(x)
}
Palette = Palette[Palette>=0]
red = bitAnd(bitShiftR(Palette,16), 255)
green = bitAnd(bitShiftR(Palette, 8), 255)
blue = bitAnd( Palette , 255)
Palette = rgb (red, green, blue, 255, maxColorValue = 255)
if (tran==-1) tran = NULL
return (list(image=x, col=Palette, transparent=tran, comment=comt))
}
# source("c:/programs/R/rw2011/src/library/caTools/R/GIF.R")
|