[go: up one dir, main page]

File: GIF.R

package info (click to toggle)
catools 1.10-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 356 kB
  • ctags: 74
  • sloc: ansic: 650; cpp: 640; makefile: 5
file content (179 lines) | stat: -rwxr-xr-x 7,064 bytes parent folder | download | duplicates (7)
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")