Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaAstro / FITSIO.jl / 206

9 Jan 2018 - 2:02 coverage: 81.889% (+0.02%) from 81.865%
206

Pull #92

travis-ci

9181eb84f9c35729a3bad740fb7f9d93?size=18&default=identiconweb-flow
Drop support for unmaintained Julia 0.5
Pull Request #92: Drop support for unmaintained Julia 0.5

633 of 773 relevant lines covered (81.89%)

39.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.86
/src/libcfitsio.jl
1
# cfitsio.jl - C-style interface to CFITSIO functions:
2
#
3
# - Function names closely mirror the C interface (e.g., `fits_open_file()`).
4
# - Functions operate on `FITSFile`, a thin wrapper for `fitsfile` C struct
5
#   (`FITSFile` has concept of "current HDU", as in CFITSIO).
6
# - Note that the wrapper functions *do* check the return status from CFITSIO
7
#   and throw an error with the appropriate message.
8
#
9
#
10
# The following table gives the correspondances between CFITSIO "types",
11
# the BITPIX keyword and Julia types.
12
#
13
#     -------------------------------------------------
14
#     CODE  CFISTIO         Julia     Comments
15
#     -------------------------------------------------
16
#           int             Cint
17
#           long            Clong
18
#           LONGLONG        Int64     64-bit integer
19
#     -------------------------------------------------
20
#     -------- FITS BITPIX ----------------------------
21
#        8  BYTE_IMG        Uint8
22
#       16  SHORT_IMG       Int16
23
#       32  LONG_IMG        Int32
24
#       64  LONGLONG_IMG    Int64
25
#      -32  FLOAT_IMG       Float32
26
#      -64  DOUBLE_IMG      Float64
27
#      -------- cfitsio "aliases" ---------------------
28
#       10  SBYTE_IMG       Int8     written as: BITPIX = 8, BSCALE = 1,
29
#                                                BZERO = -128
30
#       20  USHORT_IMG      Uint16   written as: BITPIX = 16, BSCALE = 1,
31
#                                                BZERO = 32768
32
#       40  LONG_IMG        Uint32   written as: BITPIX = 32, BSCALE = 1,
33
#                                                BZERO = 2147483648
34
#     -------------------------------------------------
35
#     -------- FITS TABLE DATA TYPES ------------------
36
#        1  TBIT
37
#       11  TBYTE           Cuchar = Uint8
38
#       12  TSBYTE          Cchar = Int8
39
#       14  TLOGICAL        Bool
40
#       16  TSTRING         String
41
#       20  TUSHORT         Cushort
42
#       21  TSHORT          Cshort
43
#       30  TUINT           Cuint
44
#       31  TINT            Cint
45
#       40  TULONG          Culong
46
#       41  TLONG           Clong
47
#       42  TFLOAT          Cfloat
48
#       81  TLONGLONG       Int64
49
#       82  TDOUBLE         Cdouble
50
#       83  TCOMPLEX        Complex{Cfloat}
51
#      163  TDBLCOMPLEX     Complex{Cdouble}
52
#     -------------------------------------------------
53
#
54

55
isdefined(Base, :__precompile__) && __precompile__()
56

57
module Libcfitsio
58

59
export FITSFile,
60
       FITSMemoryHandle,
61
       fits_assert_open,
62
       fits_clobber_file,
63
       fits_close_file,
64
       fits_copy_image_section,
65
       fits_create_ascii_tbl,
66
       fits_create_binary_tbl,
67
       fits_create_file,
68
       fits_create_img,
69
       fits_delete_file,
70
       fits_delete_key,
71
       fits_delete_record,
72
       fits_delete_rows,
73
       fits_file_mode,
74
       fits_file_name,
75
       fits_get_hdrspace,
76
       fits_get_hdu_num,
77
       fits_get_hdu_type,
78
       fits_get_img_dim,
79
       fits_get_img_equivtype,
80
       fits_get_img_size,
81
       fits_get_img_type,
82
       fits_get_num_cols,
83
       fits_get_num_hdus,
84
       fits_get_num_rows,
85
       fits_get_rowsize,
86
       fits_get_colnum,
87
       fits_get_coltype,
88
       fits_get_eqcoltype,
89
       fits_get_version,
90
       fits_read_tdim,
91
       fits_hdr2str,
92
       fits_insert_rows,
93
       fits_movabs_hdu,
94
       fits_movrel_hdu,
95
       fits_movnam_hdu,
96
       fits_open_data,
97
       fits_open_file,
98
       fits_open_image,
99
       fits_open_table,
100
       fits_open_memfile,
101
       fits_read_col,
102
       fits_read_descript,
103
       fits_read_keyn,
104
       fits_read_key_str,
105
       fits_read_key_lng,
106
       fits_read_keys_lng,
107
       fits_read_keyword,
108
       fits_read_pix,
109
       fits_read_record,
110
       fits_read_subset,
111
       fits_update_key,
112
       fits_write_col,
113
       fits_write_date,
114
       fits_write_comment,
115
       fits_write_history,
116
       fits_write_key,
117
       fits_write_pix,
118
       fits_write_record,
119
       fits_write_tdim
120

121
if isfile(joinpath(dirname(@__FILE__),"..","deps","deps.jl"))
122
    include("../deps/deps.jl")
123
else
124
    error("FITSIO not properly installed. Please run Pkg.build(\"FITSIO\")")
125
end
126

127
const TYPE_FROM_BITPIX = Dict{Cint, DataType}()
128
for (T, code) in ((UInt8,     8), # BYTE_IMG
129
                  (Int16,    16), # SHORT_IMG
130
                  (Int32,    32), # LONG_IMG
131
                  (Int64,    64), # LONGLONG_IMG
132
                  (Float32, -32), # FLOAT_IMG
133
                  (Float64, -64), # DOUBLE_IMG
134
                  (Int8,     10), # SBYTE_IMG
135
                  (UInt16,   20), # USHORT_IMG
136
                  (UInt32,   40)) # ULONG_IMG
137
    local value = Cint(code)
138
    @eval begin
139
        TYPE_FROM_BITPIX[$value] = $T
140
        bitpix_from_type(::Type{$T}) = $value
30×
141
    end
142
end
143

144
for (T, code) in ((UInt8,       11),
145
                  (Int8,        12),
146
                  (Bool,        14),
147
                  (String,      16),
148
                  (Cushort,     20),
149
                  (Cshort,      21),
150
                  (Cuint,       30),
151
                  (Cint,        31),
152
                  (Int64,       81),
153
                  (Float32,     42),
154
                  (Float64,     82),
155
                  (Complex64,   83),
156
                  (Complex128, 163))
157
    @eval cfitsio_typecode(::Type{$T}) = Cint($code)
332×
158
end
159

160
# Above, we don't define a method for Clong because it is either Cint (Int32)
161
# or Int64 depending on the platform, and those methods are already defined.
162
# Culong is either UInt64 or Cuint depending on platform. Only define it if
163
# not already defined.
164
if Culong !== Cuint
165
    cfitsio_typecode(::Type{Culong}) = Cint(40)
!
166
end
167

168
# -----------------------------------------------------------------------------
169
# FITSFile type
170

171
mutable struct FITSFile
172
    ptr::Ptr{Void}
173

174
    function FITSFile(ptr::Ptr{Void})
175
        f = new(ptr)
24×
176
        finalizer(f, fits_close_file)
24×
177
        f
24×
178
    end
179
end
180

181
# FITS wants to be able to update the ptr, so keep them
182
# in a mutable struct
183
mutable struct FITSMemoryHandle
184
    ptr::Ptr{Void}
16×
185
    size::Csize_t
186
end
187
FITSMemoryHandle() = FITSMemoryHandle(C_NULL, 0)
14×
188

189
# -----------------------------------------------------------------------------
190
# error messaging
191

192
function fits_assert_open(f::FITSFile)
193
    if f.ptr == C_NULL
972×
UNCOV
194
        error("attempt to access closed FITS file")
!
195
    end
196
end
197

198
function fits_get_errstatus(status::Cint)
199
    msg = Vector{UInt8}(31)
!
200
    ccall((:ffgerr,libcfitsio), Void, (Cint,Ptr{UInt8}), status, msg)
!
201
    unsafe_string(pointer(msg))
!
202
end
203

204
function fits_assert_ok(status::Cint, filename = nothing)
205
    if status != 0
4,342×
206
        prefix = filename == nothing ? "" : "While processing file `$filename`: "
!
UNCOV
207
        error(string(prefix, fits_get_errstatus(status)))
!
208
    end
209
end
210

211
fits_assert_isascii(str::String) =
344×
212
    !isascii(str) && error("FITS file format accepts ASCII strings only")
213

214
fits_get_version() = ccall((:ffvers, libcfitsio), Cfloat, (Ptr{Cfloat},), &0.)
2×
215

216
# -----------------------------------------------------------------------------
217
# file access & info functions
218

219
"""
220
    fits_create_file(filename::AbstractString)
221

222
Create and open a new empty output `FITSFile`.
223
"""
224
function fits_create_file(filename::AbstractString)
225
    ptr = Ref{Ptr{Void}}()
16×
226
    status = Ref{Cint}(0)
16×
227
    ccall((:ffinit,libcfitsio), Cint, (Ref{Ptr{Void}},Ptr{UInt8},Ref{Cint}),
16×
228
          ptr, filename, status)
229
    fits_assert_ok(status[], filename)
16×
230
    FITSFile(ptr[])
16×
231
end
232

233
"""
234
    fits_clobber_file(filename::AbstractString)
235

236
Like [`fits_create_file`](@ref), but overwrites `filename` if it exists.
237
"""
238
fits_clobber_file(filename::AbstractString) = fits_create_file("!"*filename)
!
239

240
"""
241
    fits_open_data(filename::String)
242

243
Open an existing data file (like [`fits_open_file`](@ref)) and move to the first HDU
244
containing either an image or a table.
245
"""
246
function fits_open_data end
247

248
"""
249
    fits_open_file(filename::String)
250

251
Open an existing data file.
252
"""
253
function fits_open_file end
254

255
"""
256
    fits_open_image(filename::String)
257

258
Open an existing data file (like [`fits_open_file`](@ref)) and move to the first
259
HDU containing an image.
260
"""
261
function fits_open_image end
262

263
"""
264
    fits_open_table(filename::String)
265

266
Open an existing data file (like [`fits_open_file`](@ref)) and move to the first
267
HDU containing either an ASCII or a binary table.
268
"""
269
function fits_open_table end
270

271
for (a,b) in ((:fits_open_data, "ffdopn"),
272
              (:fits_open_file, "ffopen"),
273
              (:fits_open_image,"ffiopn"),
274
              (:fits_open_table,"fftopn"))
275
    @eval begin
276
        function ($a)(filename::AbstractString, mode::Integer=0)
277
            ptr = Ref{Ptr{Void}}()
10×
278
            status = Ref{Cint}(0)
6×
279
            ccall(($b,libcfitsio), Cint,
6×
280
                  (Ref{Ptr{Void}},Ptr{UInt8},Cint,Ref{Cint}),
281
                  ptr, filename, mode, status)
282
            fits_assert_ok(status[], filename)
6×
283
            FITSFile(ptr[])
6×
284
        end
285
    end
286
end
287

288
# filename is ignored by the C library
289
function fits_open_memfile(data::Vector{UInt8}, mode::Integer=0, filename="")
290
    # Only reading is supported right now
291
    @assert mode == 0
4×
292
    ptr = Ref{Ptr{Void}}(C_NULL)
2×
293
    status = Ref{Cint}(0)
2×
294
    handle = FITSMemoryHandle(pointer(data),length(data))
2×
295
    dataptr = Ptr{Ptr{Void}}(pointer_from_objref(handle))
2×
296
    sizeptr = Ptr{Csize_t}(dataptr+sizeof(Ptr{Void}))
2×
297
    ccall(("ffomem",libcfitsio), Cint,
2×
298
      (Ptr{Ptr{Void}},Ptr{UInt8},Cint,Ptr{Ptr{UInt8}},
299
       Ptr{Csize_t}, Csize_t, Ptr{Void}, Ptr{Cint}),
300
       ptr, filename, mode, dataptr, sizeptr, 2880, C_NULL, status)
301
    fits_assert_ok(status[])
2×
302
    FITSFile(ptr[]), handle
2×
303
end
304

305
"""
306
    fits_close_file(f::FITSFile)
307

308
Close a previously opened FITS file.
309

310
"""
311
function fits_close_file end
312

313
"""
314
    fits_delete_file(f::FITSFile)
315

316
Close an opened FITS file (like [`fits_close_file`](@ref)) and removes it from the disk.
317
"""
318
function fits_delete_file end
319

320
for (a,b) in ((:fits_close_file, "ffclos"),
321
              (:fits_delete_file,"ffdelt"))
322
    @eval begin
323
        function ($a)(f::FITSFile)
324

325
            # fits_close_file() is called during garbage collection, but file
326
            # may already be closed by user, so we need to check if it is open.
327
            if f.ptr != C_NULL
32×
328
                status = Ref{Cint}(0)
24×
329
                ccall(($b,libcfitsio), Cint,
24×
330
                      (Ptr{Void},Ref{Cint}),
331
                      f.ptr, status)
332
                fits_assert_ok(status[])
24×
333
                f.ptr = C_NULL
24×
334
            end
335
        end
336
    end
337
end
338

339
Base.close(f::FITSFile) = fits_close_file(f)
!
340

341
"""
342
    fits_file_name(f::FITSFile)
343

344
Return the name of the file associated with object `f`.
345
"""
346
function fits_file_name(f::FITSFile)
347
    value = Vector{UInt8}(1025)
4×
348
    status = Ref{Cint}(0)
4×
349
    ccall((:ffflnm,libcfitsio), Cint,
4×
350
          (Ptr{Void},Ptr{UInt8},Ref{Cint}),
351
          f.ptr, value, status)
352
    fits_assert_ok(status[])
4×
353
    unsafe_string(pointer(value))
4×
354
end
355

356
function fits_file_mode(f::FITSFile)
357
    result = Ref{Cint}(0)
!
358
    status = Ref{Cint}(0)
!
359
    ccall(("ffflmd", libcfitsio), Cint, (Ptr{Void}, Ref{Cint}, Ref{Cint}),
!
360
          f.ptr, result, status)
361
    fits_assert_ok(status[])
!
362
    result[]
!
363
end
364

365

366
# -----------------------------------------------------------------------------
367
# header access functions
368

369
"""
370
    fits_get_hdrspace(f::FITSFile) -> (keysexist, morekeys)
371

372
Return the number of existing keywords (not counting the END keyword)
373
and the amount of space currently available for more keywords.
374
"""
375
function fits_get_hdrspace(f::FITSFile)
376
    keysexist = Ref{Cint}(0)
10×
377
    morekeys = Ref{Cint}(0)
10×
378
    status = Ref{Cint}(0)
10×
379
    ccall((:ffghsp,libcfitsio), Cint,
10×
380
        (Ptr{Void},Ref{Cint},Ref{Cint},Ref{Cint}),
381
        f.ptr, keysexist, morekeys, status)
382
    fits_assert_ok(status[])
10×
383
    (keysexist[], morekeys[])
10×
384
end
385

386
function fits_read_key_str(f::FITSFile, keyname::String)
387
    value = Vector{UInt8}(71)
12×
388
    comment = Vector{UInt8}(71)
12×
389
    status = Ref{Cint}(0)
12×
390
    ccall((:ffgkys, libcfitsio), Cint,
12×
391
          (Ptr{Void}, Ptr{UInt8}, Ptr{UInt8}, Ptr{UInt8}, Ref{Cint}),
392
          f.ptr, keyname, value, comment, status)
393
    fits_assert_ok(status[])
12×
394
    unsafe_string(pointer(value)), unsafe_string(pointer(comment))
12×
395
end
396

397
function fits_read_key_lng(f::FITSFile, keyname::String)
398
    value = Ref{Clong}(0)
8×
399
    comment = Vector{UInt8}(71)
8×
400
    status = Ref{Cint}(0)
8×
401
    ccall((:ffgkyj, libcfitsio), Cint,
8×
402
          (Ptr{Void}, Ptr{UInt8}, Ref{Clong}, Ptr{UInt8}, Ref{Cint}),
403
          f.ptr, keyname, value, comment, status)
404
    fits_assert_ok(status[])
8×
405
    value[], unsafe_string(pointer(comment))
8×
406
end
407

408
function fits_read_keys_lng(f::FITSFile, keyname::String,
409
                            nstart::Integer, nmax::Integer)
410
    value = Vector{Clong}(nmax - nstart + 1)
4×
411
    nfound = Ref{Cint}(0)
4×
412
    status = Ref{Cint}(0)
4×
413
    ccall((:ffgknj, libcfitsio), Cint,
4×
414
          (Ptr{Void}, Ptr{UInt8}, Cint, Cint, Ptr{Clong}, Ref{Cint}, Ref{Cint}),
415
          f.ptr, keyname, nstart, nmax, value, nfound, status)
416
    fits_assert_ok(status[])
4×
417
    value, nfound[]
4×
418
end
419

420
"""
421
    fits_read_keyword(f::FITSFile, keyname::String) -> (value, comment)
422

423
Return the specified keyword.
424
"""
425
function fits_read_keyword(f::FITSFile, keyname::String)
426
    value = Vector{UInt8}(71)
12×
427
    comment = Vector{UInt8}(71)
12×
428
    status = Ref{Cint}(0)
12×
429
    ccall((:ffgkey,libcfitsio), Cint,
12×
430
        (Ptr{Void},Ptr{UInt8},Ptr{UInt8},Ptr{UInt8},Ref{Cint}),
431
        f.ptr, keyname, value, comment, status)
432
    fits_assert_ok(status[])
12×
433
    unsafe_string(pointer(value)), unsafe_string(pointer(comment))
12×
434
end
435

436

437
"""
438
    fits_read_record(f::FITSFile, keynum::Int) -> String
439

440
Return the nth header record in the CHU. The first keyword in the
441
header is at `keynum = 1`.
442
"""
443
function fits_read_record(f::FITSFile, keynum::Integer)
444
    card = Vector{UInt8}(81)
!
445
    status = Ref{Cint}(0)
!
446
    ccall((:ffgrec,libcfitsio), Cint,
!
447
        (Ptr{Void},Cint,Ptr{UInt8},Ref{Cint}),
448
        f.ptr, keynum, card, status)
449
    fits_assert_ok(status[])
!
450
    unsafe_string(pointer(card))
!
451
end
452

453

454
"""
455
    fits_read_keyn(f::FITSFile, keynum::Int) -> (name, value, comment)
456

457
Return the nth header record in the CHU. The first keyword in the header is at `keynum = 1`.
458
"""
459
function fits_read_keyn(f::FITSFile, keynum::Integer)
460
    keyname = Vector{UInt8}(9)
12×
461
    value = Vector{UInt8}(71)
12×
462
    comment = Vector{UInt8}(71)
12×
463
    status = Ref{Cint}(0)
12×
464
    ccall((:ffgkyn,libcfitsio), Cint,
12×
465
        (Ptr{Void},Cint,Ptr{UInt8},Ptr{UInt8},Ptr{UInt8},Ref{Cint}),
466
        f.ptr, keynum, keyname, value, comment, status)
467
    fits_assert_ok(status[])
12×
468
    (unsafe_string(pointer(keyname)), unsafe_string(pointer(value)),
12×
469
     unsafe_string(pointer(comment)))
470
end
471

472
"""
473
    fits_write_key(f::FITSFile, keyname::String, value, comment::String)
474

475
Write a keyword of the appropriate data type into the CHU.
476
"""
477
function fits_write_key(f::FITSFile, keyname::String,
478
                        value::Union{Real,String}, comment::String)
479
    fits_assert_isascii(keyname)
16×
480
    fits_assert_isascii(comment)
16×
481
    cvalue = isa(value,String) ?  value :
16×
482
             isa(value,Bool) ? Cint[value] : reinterpret(UInt8, [value])
483
    status = Ref{Cint}(0)
16×
484
    ccall((:ffpky,libcfitsio), Cint,
16×
485
        (Ptr{Void},Cint,Ptr{UInt8},Ptr{UInt8},Ptr{UInt8},Ref{Cint}),
486
        f.ptr, cfitsio_typecode(typeof(value)), keyname,
487
        cvalue, comment, status)
488
    fits_assert_ok(status[])
16×
489
end
490

491
function fits_write_date(f::FITSFile)
492
    status = Ref{Cint}(0)
4×
493
    ccall((:ffpdat, libcfitsio), Cint, (Ptr{Void}, Ref{Cint}), f.ptr, status)
4×
494
    fits_assert_ok(status[])
4×
495
end
496

497
function fits_write_comment(f::FITSFile, comment::String)
498
    fits_assert_isascii(comment)
8×
499
    status = Ref{Cint}(0)
8×
500
    ccall((:ffpcom, libcfitsio), Cint, (Ptr{Void}, Ptr{UInt8}, Ref{Cint}),
8×
501
          f.ptr, comment, status)
502
    fits_assert_ok(status[])
8×
503
end
504

505
function fits_write_history(f::FITSFile, history::String)
506
    fits_assert_isascii(history)
4×
507
    status = Ref{Cint}(0)
4×
508
    ccall((:ffphis, libcfitsio), Cint, (Ptr{Void}, Ptr{UInt8}, Ref{Cint}),
4×
509
          f.ptr, history, status)
510
    fits_assert_ok(status[])
4×
511
end
512

513
# update key: if already present, update it, otherwise add it.
514
for (a,T,S) in (("ffukys", :String, :(Ptr{UInt8})),
515
                ("ffukyl", :Bool,        :Cint),
516
                ("ffukyj", :Integer,     :Int64))
517
    @eval begin
518
        function fits_update_key(f::FITSFile, key::String, value::$T,
519
                                 comment::Union{String, Ptr{Void}}=C_NULL)
520
            isa(value, String) && fits_assert_isascii(value)
20×
521
            isa(comment, String) && fits_assert_isascii(comment)
20×
522
            status = Ref{Cint}(0)
20×
523
            ccall(($a, libcfitsio), Cint,
20×
524
                  (Ptr{Void}, Ptr{UInt8}, $S, Ptr{UInt8}, Ref{Cint}),
525
                  f.ptr, key, value, comment, status)
526
            fits_assert_ok(status[])
20×
527
        end
528
    end
529
end
530

531
function fits_update_key(f::FITSFile, key::String, value::AbstractFloat,
532
                         comment::Union{String, Ptr{Void}}=C_NULL)
533
    isa(comment, String) && fits_assert_isascii(comment)
8×
534
    status = Ref{Cint}(0)
8×
535
    ccall(("ffukyd", libcfitsio), Cint,
8×
536
          (Ptr{Void}, Ptr{UInt8}, Cdouble, Cint, Ptr{UInt8}, Ref{Cint}),
537
          f.ptr, key, value, -15, comment, status)
538
    fits_assert_ok(status[])
8×
539
end
540

541
function fits_update_key(f::FITSFile, key::String, value::Void,
542
                         comment::Union{String, Ptr{Void}}=C_NULL)
543
    isa(comment, String) && fits_assert_isascii(comment)
4×
544
    status = Ref{Cint}(0)
4×
545
    ccall(("ffukyu", libcfitsio), Cint,
4×
546
          (Ptr{Void}, Ptr{UInt8}, Ptr{UInt8}, Ref{Cint}),
547
          f.ptr, key, comment, status)
548
    fits_assert_ok(status[])
4×
549
end
550

551
"""
552
    fits_write_record(f::FITSFile, card::String)
553

554
Write a user specified keyword record into the CHU.
555
"""
556
function fits_write_record(f::FITSFile, card::String)
557
    fits_assert_isascii(card)
!
558
    status = Ref{Cint}(0)
!
559
    ccall((:ffprec,libcfitsio), Cint,
!
560
        (Ptr{Void},Ptr{UInt8},Ref{Cint}),
561
        f.ptr, card, status)
562
    fits_assert_ok(status[])
!
563
end
564

565
"""
566
    fits_delete_record(f::FITSFile, keynum::Int)
567

568
Delete the keyword record at the specified index.
569
"""
570
function fits_delete_record(f::FITSFile, keynum::Integer)
571
    status = Ref{Cint}(0)
!
572
    ccall((:ffdrec,libcfitsio), Cint,
!
573
        (Ptr{Void},Cint,Ref{Cint}),
574
        f.ptr, keynum, status)
575
    fits_assert_ok(status[])
!
576
end
577

578
"""
579
    fits_delete_key(f::FITSFile, keyname::String)
580

581
Delete the keyword named `keyname`.
582
"""
583
function fits_delete_key(f::FITSFile, keyname::String)
584
    status = Ref{Cint}(0)
!
585
    ccall((:ffdkey,libcfitsio), Cint,
!
586
        (Ptr{Void},Ptr{UInt8},Ref{Cint}),
587
        f.ptr, keyname, status)
588
    fits_assert_ok(status[])
!
589
end
590

591
"""
592
    fits_hdr2str(f::FITSFile, nocomments::Bool=false)
593

594
Return the header of the CHDU as a string. If `nocomments` is `true`, comment
595
cards are stripped from the output.
596
"""
597
function fits_hdr2str(f::FITSFile, nocomments::Bool=false)
598
    status = Ref{Cint}(0)
8×
599
    header = Ref{Ptr{UInt8}}()
4×
600
    nkeys = Ref{Cint}(0)
4×
601
    ccall((:ffhdr2str, libcfitsio), Cint,
4×
602
          (Ptr{Void}, Cint, Ptr{Ptr{UInt8}}, Cint,
603
           Ptr{Ptr{UInt8}}, Ref{Cint}, Ref{Cint}),
604
          f.ptr, nocomments, &C_NULL, 0, header, nkeys, status)
605
    result = unsafe_string(header[])
4×
606

607
    # free header pointer allocated by cfitsio (result is a copy)
608
    ccall((:fffree, libcfitsio), Ref{Cint},
4×
609
          (Ptr{UInt8}, Ref{Cint}),
610
          header[], status)
611
    fits_assert_ok(status[])
4×
612
    result
4×
613
end
614

615

616
# -----------------------------------------------------------------------------
617
# HDU info functions and moving the current HDU
618

619
function hdu_int_to_type(hdu_type_int)
620
    if hdu_type_int == 0
394×
621
        return :image_hdu
338×
622
    elseif hdu_type_int == 1
56×
623
        return :ascii_table
12×
624
    elseif hdu_type_int == 2
44×
625
        return :binary_table
44×
626
    end
627

628
    :unknown
!
629
end
630

631
"""
632
    fits_movabs_hdu(f::FITSFile, hduNum::Integer)
633

634
Change the current HDU to the value specified by `hduNum`, and return a symbol
635
describing the type of the HDU.
636

637
Possible symbols are: `image_hdu`, `ascii_table`, or `binary_table`.
638
The value of `hduNum` must range between 1 and the value returned by
639
[`fits_get_num_hdus`](@ref).
640
"""
641
function fits_movabs_hdu end
642

643
"""
644
    fits_movrel_hdu(f::FITSFile, hduNum::Integer)
645

646
Change the current HDU by moving forward or backward by `hduNum` HDUs
647
(positive means forward), and return the same as [`fits_movabs_hdu`](@ref).
648
"""
649
function fits_movrel_hdu end
650
for (a,b) in ((:fits_movabs_hdu,"ffmahd"),
651
              (:fits_movrel_hdu,"ffmrhd"))
652
    @eval begin
653
        function ($a)(f::FITSFile, hduNum::Integer)
654
            hdu_type = Ref{Cint}(0)
394×
655
            status = Ref{Cint}(0)
394×
656
            ccall(($b,libcfitsio), Cint,
394×
657
                  (Ptr{Void}, Cint, Ref{Cint}, Ref{Cint}),
658
                  f.ptr, hduNum, hdu_type, status)
659
            fits_assert_ok(status[])
394×
660
            hdu_int_to_type(hdu_type[])
394×
661
        end
662
    end
663
end
664

665
"""
666
    fits_movnam_hdu(f::FITSFile, extname::String, extver::Integer=0,
667
                    hdu_type_int::Integer=-1)
668

669
Change the current HDU by moving to the (first) HDU which has the specified
670
extension type and EXTNAME and EXTVER keyword values (or HDUNAME and HDUVER keywords).
671

672
If `extver` is 0 (the default) then the EXTVER keyword is ignored and the first HDU
673
with a matching EXTNAME (or HDUNAME) keyword will be found. If `hdu_type_int`
674
is -1 (the default) only the extname and extver values will be used to locate the
675
correct extension. If no matching HDU is found in the file, the current HDU will
676
remain unchanged.
677
"""
678
function fits_movnam_hdu(f::FITSFile, extname::String, extver::Integer=0,
679
                         hdu_type::Integer=-1)
680
    status = Ref{Cint}(0)
!
681
    ccall((:ffmnhd,libcfitsio), Cint,
!
682
          (Ptr{Void}, Cint, Ptr{UInt8}, Cint, Ref{Cint}),
683
          f.ptr, hdu_type, extname, extver, status)
684
    fits_assert_ok(status[])
!
685
end
686

687
function fits_get_hdu_num(f::FITSFile)
688
    hdunum = Ref{Cint}(0)
!
689
    ccall((:ffghdn,libcfitsio), Cint,
!
690
          (Ptr{Void}, Ref{Cint}),
691
          f.ptr, hdunum)
692
    hdunum[]
!
693
end
694

695
function fits_get_hdu_type(f::FITSFile)
696
    hdutype = Ref{Cint}(0)
!
697
    status = Ref{Cint}(0)
!
698
    ccall((:ffghdt, libcfitsio), Cint,
!
699
          (Ptr{Void}, Ref{Cint}, Ref{Cint}),
700
          f.ptr, hdutype, status)
701
    fits_assert_ok(status[])
!
702
    hdu_int_to_type(hdutype[])
!
703
end
704

705
# -----------------------------------------------------------------------------
706
# image HDU functions
707

708
"""
709
    fits_get_img_size(f::FITSFile)
710

711
Get the dimensions of the image.
712
"""
713
function fits_get_img_size end
714
for (a, b) in ((:fits_get_img_type,      "ffgidt"),
715
               (:fits_get_img_equivtype, "ffgiet"),
716
               (:fits_get_img_dim,       "ffgidm"))
717
    @eval function ($a)(f::FITSFile)
718
        result = Ref{Cint}(0)
364×
719
        status = Ref{Cint}(0)
364×
720
        ccall(($b, libcfitsio), Cint, (Ptr{Void}, Ref{Cint}, Ref{Cint}),
364×
721
              f.ptr, result, status)
722
        fits_assert_ok(status[])
364×
723
        result[]
364×
724
    end
725
end
726

727
"""
728
    fits_create_img(f::FITSFile, t::Type, naxes::Vector{Int})
729

730
Create a new primary array or IMAGE extension with a specified data type and size.
731
"""
732
function fits_create_img{T, S<:Integer}(f::FITSFile, ::Type{T},
733
                                        naxes::Vector{S})
734
    status = Ref{Cint}(0)
30×
735
    ccall((:ffcrimll, libcfitsio), Cint,
30×
736
          (Ptr{Void}, Cint, Cint, Ptr{Int64}, Ref{Cint}),
737
          f.ptr, bitpix_from_type(T), length(naxes),
738
          Vector{Int64}(naxes), status)
739
    fits_assert_ok(status[])
30×
740
end
741

742
"""
743
    fits_write_pix(f::FITSFile, fpixel::Vector{Int}, nelements::Int, data::Array)
744

745
Write pixels from `data` into the FITS file.
746
"""
747
function fits_write_pix{S<:Integer,T}(f::FITSFile, fpixel::Vector{S},
748
                                      nelements::Integer, data::Array{T})
749
    status = Ref{Cint}(0)
26×
750
    ccall((:ffppxll, libcfitsio), Cint,
26×
751
          (Ptr{Void}, Cint, Ptr{Int64}, Int64, Ptr{Void}, Ref{Cint}),
752
          f.ptr, cfitsio_typecode(T), Vector{Int64}(fpixel),
753
          nelements, data, status)
754
    fits_assert_ok(status[])
26×
755
end
756

757
function fits_write_pix(f::FITSFile, data::Array)
758
    fits_write_pix(f, ones(Int64, length(size(data))), length(data), data)
!
759
end
760

761
function fits_read_pix{S<:Integer,T}(f::FITSFile, fpixel::Vector{S},
762
                                     nelements::Int, nullval::T,
763
                                     data::Array{T})
764
    anynull = Ref{Cint}(0)
!
765
    status = Ref{Cint}(0)
!
766
    ccall((:ffgpxvll, libcfitsio), Cint,
!
767
          (Ptr{Void}, Cint, Ptr{Int64}, Int64, Ptr{Void}, Ptr{Void},
768
           Ref{Cint}, Ref{Cint}),
769
          f.ptr, cfitsio_typecode(T), Vector{Int64}(fpixel),
770
          nelements, &nullval, data, anynull, status)
771
    fits_assert_ok(status[])
!
772
    anynull[]
!
773
end
774

775
"""
776
    fits_read_pix(f::FITSFile, fpixel::Vector{Int}, nelements::Int, data::Array)
777

778
Read pixels from the FITS file into `data`.
779
"""
780
function fits_read_pix{S<:Integer,T}(f::FITSFile, fpixel::Vector{S},
781
                                     nelements::Int, data::Array{T})
782
    anynull = Ref{Cint}(0)
26×
783
    status = Ref{Cint}(0)
26×
784
    ccall((:ffgpxvll, libcfitsio), Cint,
26×
785
          (Ptr{Void}, Cint, Ptr{Int64}, Int64, Ptr{Void}, Ptr{Void},
786
           Ref{Cint}, Ref{Cint}),
787
          f.ptr, cfitsio_typecode(T), Vector{Int64}(fpixel),
788
          nelements, C_NULL, data, anynull, status)
789
    fits_assert_ok(status[])
26×
790
    anynull[]
26×
791
end
792

793
function fits_read_pix(f::FITSFile, data::Array)
794
    fits_read_pix(f, ones(Int64,length(size(data))), length(data), data)
26×
795
end
796

797
function fits_read_subset{S1<:Integer,S2<:Integer,S3<:Integer,T}(
798
             f::FITSFile, fpixel::Vector{S1}, lpixel::Vector{S2},
799
             inc::Vector{S3}, data::Array{T})
800
    anynull = Ref{Cint}(0)
108×
801
    status = Ref{Cint}(0)
108×
802
    ccall((:ffgsv, libcfitsio), Cint,
108×
803
          (Ptr{Void}, Cint, Ptr{Clong}, Ptr{Clong}, Ptr{Clong}, Ptr{Void},
804
           Ptr{Void}, Ref{Cint}, Ref{Cint}),
805
          f.ptr, cfitsio_typecode(T),
806
          Vector{Clong}(fpixel),
807
          Vector{Clong}(lpixel),
808
          Vector{Clong}(inc),
809
          C_NULL, data, anynull, status)
810
    fits_assert_ok(status[])
108×
811
    anynull[]
108×
812
end
813

814
function fits_copy_image_section(fin::FITSFile, fout::FITSFile,
815
                                 section::String)
816
    status = Ref{Cint}(0)
4×
817
    ccall((:fits_copy_image_section,libcfitsio), Cint,
4×
818
          (Ptr{Void}, Ptr{Void}, Ptr{UInt8}, Ref{Cint}),
819
          fin.ptr, fout.ptr, section, status)
820
    fits_assert_ok(status[])
4×
821
end
822

823

824
# -----------------------------------------------------------------------------
825
# ASCII/binary table HDU functions
826

827
# The three fields are: ttype, tform, tunit (CFITSIO's terminology)
828
const ColumnDef = Tuple{String, String, String}
829

830
"""
831
    fits_create_binary_tbl(f::FITSFile, numrows::Integer, coldefs::Array{ColumnDef},
832
                           extname::String)
833

834
Append a new HDU containing a binary table. The meaning of the parameters is the same
835
as in a call to [`fits_create_ascii_tbl`](@ref).
836

837
In general, one should pick this function for creating tables in a new HDU,
838
as binary tables require less space on the disk and are more efficient to read and write.
839
(Moreover, a few datatypes are not supported in ASCII tables).
840
"""
841
function fits_create_binary_tbl end
842

843
"""
844
    fits_create_ascii_tbl(f::FITSFile, numrows::Integer, coldefs::Array{ColumnDef},
845
                          extname::String)
846

847
Append a new HDU containing an ASCII table.
848

849
The table will have `numrows` rows (this parameter can be set to zero), each
850
initialized with the default value. In order to create a table, the programmer
851
must specify the characteristics of each column. The columns are specified by the
852
`coldefs` variable, which is an array of tuples.
853
Each tuple must have three string fields:
854

855
1. The name of the column.
856
2. The data type and the repetition count. It must be a string made by a number
857
   (the repetition count) followed by a letter specifying the type (in the example
858
   above, `D` stands for `Float64`, `E` stands for `Float32`, `A` stands for `Char`).
859
   Refer to the CFITSIO documentation for more information about the syntax of this
860
   parameter.
861
3. The measure unit of this field. This is used only as a comment.
862

863
The value of `extname` sets the "extended name" of the table, i.e., a string
864
that in some situations can be used to refer to the HDU itself.
865

866
Note that, unlike for binary tables, CFITSIO puts some limitations to the
867
types that can be used in an ASCII table column. Refer to the CFITSIO manual
868
for further information.
869

870
See also [`fits_create_binary_tbl`](@ref) for a similar function which
871
creates binary tables.
872
"""
873
function fits_create_ascii_tbl end
874
for (a,b) in ((:fits_create_binary_tbl, 2),
875
              (:fits_create_ascii_tbl,  1))
876
    @eval begin
877
        function ($a)(f::FITSFile, numrows::Integer,
878
                      coldefs::Array{ColumnDef}, extname::String)
879

880
            # Ensure that extension name, column names and units are
881
            # ASCII, as these get written to the file. We don't check
882
            # need to check that tform is ASCII because presumably
883
            # cfitsio will thrown an appropriate error if it doesn't
884
            # recognize the tform string.
885
            fits_assert_isascii(extname)
4×
886
            for coldef in coldefs
4×
887
                fits_assert_isascii(coldef[1])
4×
888
                fits_assert_isascii(coldef[3])
4×
889
            end
890

891
            # get length and convert coldefs to three arrays of Ptr{Uint8}
892
            ntype = length(coldefs)
4×
893
            ttype = [pointer(x[1]) for x in coldefs]
4×
894
            tform = [pointer(x[2]) for x in coldefs]
4×
895
            tunit = [pointer(x[3]) for x in coldefs]
4×
896
            status = Ref{Cint}(0)
4×
897

898
            ccall(("ffcrtb", libcfitsio), Cint,
4×
899
                  (Ptr{Void}, Cint, Int64, Cint,
900
                   Ptr{Ptr{UInt8}}, Ptr{Ptr{UInt8}},
901
                   Ptr{Ptr{UInt8}}, Ptr{UInt8}, Ref{Cint}),
902
                  f.ptr, $b, numrows, ntype,
903
                  ttype, tform, tunit, extname,
904
                  status)
905
            fits_assert_ok(status[])
4×
906
        end
907
    end
908
end
909

910
"""
911
    fits_get_num_hdus(f::FITSFile)
912

913
Return the number of HDUs in the file.
914
"""
915
function fits_get_num_hdus end
916
for (a,b,T) in ((:fits_get_num_cols,  "ffgncl",  :Cint),
917
                (:fits_get_num_hdus,  "ffthdu",  :Cint),
918
                (:fits_get_rowsize,   "ffgrsz",  :Clong))
919
    @eval begin
920
        function ($a)(f::FITSFile)
921
            result = Ref{$T}(0)
268×
922
            status = Ref{Cint}(0)
268×
923
            ccall(($b,libcfitsio), Cint,
268×
924
                  (Ptr{Void}, Ref{$T}, Ref{Cint}),
925
                  f.ptr, result, status)
926
            fits_assert_ok(status[])
268×
927
            result[]
268×
928
        end
929
    end
930
end
931

932
function fits_get_colnum(f::FITSFile, tmplt::String)
933
    result = Ref{Cint}(0)
44×
934
    status = Ref{Cint}(0)
44×
935

936
    # Second argument is case-sensitivity of search: 0 = case-insensitive
937
    #                                                1 = case-sensitive
938
    ccall(("ffgcno", libcfitsio), Cint,
44×
939
          (Ptr{Void}, Cint, Ptr{UInt8}, Ref{Cint}, Ref{Cint}),
940
          f.ptr, 0, tmplt, result, status)
941
    fits_assert_ok(status[])
44×
942
    return result[]
44×
943
end
944

945
# The following block are all functions that have separate variants for Clong
946
# and 64-bit integers in cfitsio. Rather than providing both of these, we
947
# provide only one according to the native integer type on the platform.
948
if  promote_type(Int, Clong) == Clong
949
    T = Clong
950
    ffgtdm = "ffgtdm"
951
    ffgnrw = "ffgnrw"
952
    ffptdm = "ffptdm"
953
    ffgtcl = "ffgtcl"
954
    ffeqty = "ffeqty"
955
    ffgdes = "ffgdes"
956
    ffgisz = "ffgisz"
957
else
958
    T = Int64
959
    ffgtdm = "ffgtdmll"
960
    ffgnrw = "ffgnrwll"
961
    ffptdm = "ffptdmll"
962
    ffgtcl = "ffgtclll"
963
    ffeqty = "ffeqtyll"
964
    ffgdes = "ffgdesll"
965
    ffgisz = "ffgiszll"
966
end
967

968
"""
969
    fits_get_coltype(f::FITSFile, colnum::Integer)
970

971
Provided that the current HDU contains either an ASCII or binary table, return
972
information about the column at position `colnum` (counting from 1).
973

974
Return is a tuple containing
975

976
- `typecode`: CFITSIO integer type code of the column.
977
- `repcount`: Repetition count for the column.
978
- `width`: Width of an individual element.
979
"""
980
function fits_get_coltype end
981

982
@eval begin
983
    function fits_get_coltype(ff::FITSFile, colnum::Integer)
984
        typecode = Ref{Cint}(0)
!
985
        repcnt = Ref{$T}(0)
!
986
        width = Ref{$T}(0)
!
987
        status = Ref{Cint}(0)
!
988
        ccall(($ffgtcl,libcfitsio), Cint,
!
989
              (Ptr{Void}, Cint, Ref{Cint}, Ref{$T}, Ref{$T}, Ref{Cint}),
990
              ff.ptr, colnum, typecode, repcnt, width, status)
991
        fits_assert_ok(status[])
!
992
        return Int(typecode[]), Int(repcnt[]), Int(width[])
!
993
    end
994

995
    function fits_get_eqcoltype(ff::FITSFile, colnum::Integer)
996
        typecode = Ref{Cint}(0)
84×
997
        repcnt = Ref{$T}(0)
84×
998
        width = Ref{$T}(0)
84×
999
        status = Ref{Cint}(0)
84×
1000
        ccall(($ffeqty,libcfitsio), Cint,
84×
1001
              (Ptr{Void}, Cint, Ref{Cint}, Ref{$T}, Ref{$T}, Ref{Cint}),
1002
              ff.ptr, colnum, typecode, repcnt, width, status)
1003
        fits_assert_ok(status[])
84×
1004
        return Int(typecode[]), Int(repcnt[]), Int(width[])
84×
1005
    end
1006

1007
    function fits_get_img_size(f::FITSFile)
1008
        ndim = fits_get_img_dim(f)
226×
1009
        naxes = Vector{$T}(ndim)
226×
1010
        status = Ref{Cint}(0)
226×
1011
        ccall(($ffgisz, libcfitsio), Cint,
226×
1012
              (Ptr{Void}, Cint, Ptr{$T}, Ref{Cint}),
1013
              f.ptr, ndim, naxes, status)
1014
        fits_assert_ok(status[])
226×
1015
        naxes
226×
1016
    end
1017

1018
    function fits_get_num_rows(f::FITSFile)
1019
        result = Ref{$T}(0)
44×
1020
        status = Ref{Cint}(0)
44×
1021
        ccall(($ffgnrw, libcfitsio), Cint,
44×
1022
              (Ptr{Void}, Ref{$T}, Ref{Cint}),
1023
              f.ptr, result, status)
1024
        fits_assert_ok(status[])
44×
1025
        return Int(result[])
44×
1026
    end
1027

1028
    # `fits_read_tdim` returns the dimensions of a table column in a
1029
    # binary table. Normally this information is given by the TDIMn
1030
    # keyword, but if this keyword is not present then this routine
1031
    # returns `[r]` with `r` equals to the repeat count in the TFORM
1032
    # keyword.
1033
    function fits_read_tdim(ff::FITSFile, colnum::Integer)
1034
        naxes = Vector{$T}(99)  # 99 is the maximum allowed number of axes
8×
1035
        naxis = Ref{Cint}(0)
8×
1036
        status = Ref{Cint}(0)
8×
1037
        ccall(($ffgtdm,libcfitsio), Cint,
8×
1038
              (Ptr{Void}, Cint, Cint, Ref{Cint}, Ptr{$T}, Ref{Cint}),
1039
              ff.ptr, colnum, length(naxes), naxis, naxes, status)
1040
        fits_assert_ok(status[])
8×
1041
        return naxes[1:naxis[]]
8×
1042
    end
1043

1044
    function fits_write_tdim(ff::FITSFile, colnum::Integer,
1045
                                 naxes::Array{$T})
1046
        status = Ref{Cint}(0)
30×
1047
        ccall(($ffptdm, libcfitsio), Cint,
30×
1048
              (Ptr{Void}, Cint, Cint, Ptr{$T}, Ref{Cint}),
1049
              ff.ptr, colnum, length(naxes), naxes, status)
1050
        fits_assert_ok(status[])
30×
1051
    end
1052

1053
    function fits_read_descript(f::FITSFile, colnum::Integer, rownum::Integer)
1054
        repeat = Ref{$T}(0)
80×
1055
        offset = Ref{$T}(0)
80×
1056
        status = Ref{Cint}(0)
80×
1057
        ccall(($ffgdes, libcfitsio), Cint,
80×
1058
              (Ptr{Void}, Cint, Int64, Ref{$T}, Ref{$T}, Ref{Cint}),
1059
              f.ptr, colnum, rownum, repeat, offset, status)
1060
        fits_assert_ok(status[])
80×
1061
        return Int(repeat[]), Int(offset[])
80×
1062
    end
1063
end
1064

1065
"""
1066
    fits_read_col(f, colnum, firstrow, firstelem, data)
1067

1068
Read data from one column of an ASCII/binary table and convert the data into the
1069
specified type `T`.
1070

1071
### Arguments ###
1072

1073
* `f::FITSFile`: the file to be read.
1074
* `colnum::Integer`: the column number, where the value of the first column is `1`.
1075
* `firstrow::Integer`: the elements to be read start from this row.
1076
* `firstelem::Integer`: specifies which is the first element to be read, when each
1077
  cell contains more than one element (i.e., the "repetition count" of the field is
1078
  greater than one).
1079
* `data::Array`: at the end of the call, this will be filled with the elements read
1080
  from the column. The length of the array gives the overall number of elements.
1081
"""
1082
function fits_read_col(f::FITSFile,
1083
                       colnum::Integer,
1084
                       firstrow::Integer,
1085
                       firstelem::Integer,
1086
                       data::Array{String})
1087

1088
    # get width: number of characters in each string
1089
    typecode, repcount, width = fits_get_eqcoltype(f, colnum)
6×
1090

1091
    # ensure that data are strings, otherwise cfitsio will try to write
1092
    # formatted strings, which have widths given by fits_get_col_display_width
1093
    # not by the repeat value from fits_get_coltype.
1094
    abs(typecode) == 16 || error("not a string column")
6×
1095

1096
    # create an array of character buffers of the correct width
1097
    buffers = [Vector{UInt8}(width) for i in 1:length(data)]
6×
1098

1099
    # Call the CFITSIO function
1100
    anynull = Ref{Cint}(0)
6×
1101
    status = Ref{Cint}(0)
6×
1102
    ccall((:ffgcvs, libcfitsio), Cint,
6×
1103
          (Ptr{Void}, Cint, Int64, Int64, Int64,
1104
           Ptr{UInt8}, Ptr{Ptr{UInt8}}, Ref{Cint}, Ref{Cint}),
1105
          f.ptr, colnum, firstrow, firstelem, length(data),
1106
          " ", buffers, anynull, status)
1107
    fits_assert_ok(status[])
6×
1108

1109
    # Create strings out of the buffers, terminating at null characters.
1110
    # Note that `String(x)` does not copy the buffer x.
1111
    for i in 1:length(data)
6×
1112
        zeropos = search(buffers[i], 0x00)
160×
1113
        data[i] = (zeropos >= 1) ? String(buffers[i][1:(zeropos-1)]) :
160×
1114
                                   String(buffers[i])
1115
    end
1116
end
1117

1118
function fits_read_col{T}(f::FITSFile,
1119
                          colnum::Integer,
1120
                          firstrow::Integer,
1121
                          firstelem::Integer,
1122
                          data::Array{T})
1123
    anynull = Ref{Cint}(0)
78×
1124
    status = Ref{Cint}(0)
78×
1125
    ccall((:ffgcv,libcfitsio), Cint,
78×
1126
          (Ptr{Void}, Cint, Cint, Int64, Int64, Int64,
1127
           Ptr{Void}, Ptr{Void}, Ref{Cint}, Ref{Cint}),
1128
          f.ptr, cfitsio_typecode(T), colnum,
1129
          firstrow, firstelem, length(data),
1130
          C_NULL, data, anynull, status)
1131
    fits_assert_ok(status[])
78×
1132
end
1133

1134
"""
1135
    fits_write_col(f, colnum, firstrow, firstelem, data)
1136

1137
Write some data in one column of a ASCII/binary table.
1138

1139
If there is no room for the elements, new rows will be created. (It is therefore
1140
useless to call [`fits_insert_rows`](@ref) if you only need to *append* elements
1141
to the end of a table.)
1142

1143
* `f::FITSFile`: the file in which data will be written.
1144
* `colnum::Integer`: the column number, where the value of the first column is `1`.
1145
* `firstrow::Integer`: the data wil be written from this row onwards.
1146
* `firstelem::Integer`: specifies the position in the row where the first element
1147
  will be written.
1148
* `data::Array`: contains the elements that are to be written to the column of the table.
1149
"""
1150
function fits_write_col(f::FITSFile,
1151
                        colnum::Integer,
1152
                        firstrow::Integer,
1153
                        firstelem::Integer,
1154
                        data::Array{String})
1155
    for el in data; fits_assert_isascii(el); end
166×
1156
    status = Ref{Cint}(0)
6×
1157
    ccall((:ffpcls, libcfitsio), Cint,
6×
1158
          (Ptr{Void}, Cint, Int64, Int64, Int64,
1159
           Ptr{Ptr{UInt8}}, Ref{Cint}),
1160
          f.ptr, colnum, firstrow, firstelem, length(data),
1161
          data, status)
1162
    fits_assert_ok(status[])
6×
1163
end
1164

1165
function fits_write_col{T}(f::FITSFile,
1166
                           colnum::Integer,
1167
                           firstrow::Integer,
1168
                           firstelem::Integer,
1169
                           data::Array{T})
1170
    status = Ref{Cint}(0)
78×
1171
    ccall((:ffpcl, libcfitsio), Cint,
78×
1172
          (Ptr{Void}, Cint, Cint, Int64, Int64, Int64,
1173
           Ptr{Void}, Ref{Cint}),
1174
          f.ptr, cfitsio_typecode(T), colnum,
1175
          firstrow, firstelem, length(data),
1176
          data, status)
1177
    fits_assert_ok(status[])
78×
1178
end
1179

1180
"""
1181
    fits_insert_rows(f::FITSFile, firstrow::Integer, nrows::Integer)
1182

1183
Insert a number of rows equal to `nrows` after the row number `firstrow`.
1184

1185
The elements in each row are initialized to their default value: you can
1186
modify them later using [`fits_write_col`](@ref).
1187

1188
Since the first row is at position 1, in order to insert rows *before*
1189
the first one `firstrow` must be equal to zero.
1190
"""
1191
function fits_insert_rows end
1192

1193
"""
1194
    fits_delete_rows(f::FITSFile, firstrow::integer, nrows::Integer)
1195

1196
Delete `nrows` rows, starting from the one at position `firstrow`. The index of
1197
the first row is 1.
1198
"""
1199
function fits_delete_rows end
1200

1201
for (a,b) in ((:fits_insert_rows, "ffirow"),
1202
              (:fits_delete_rows, "ffdrow"))
1203
    @eval begin
1204
        function ($a)(f::FITSFile, firstrow::Integer, nrows::Integer)
1205
            status = Ref{Cint}(0)
!
1206
            ccall(($b,libcfitsio), Cint,
!
1207
                  (Ptr{Void}, Int64, Int64, Ref{Cint}),
1208
                  f.ptr, firstrow, nrows, status)
1209
            fits_assert_ok(status[])
!
1210
        end
1211
    end
1212
end
1213

1214
end # module
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2023 Coveralls, Inc