github.com/astrogo/cfitsio@v0.1.0/phdu.go (about)

     1  package cfitsio
     2  
     3  // #include "go-cfitsio.h"
     4  // #include "go-cfitsio-utils.h"
     5  import "C"
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"unsafe"
    11  )
    12  
    13  // PrimaryHDU is the primary HDU
    14  type PrimaryHDU struct {
    15  	ImageHDU
    16  }
    17  
    18  // Name returns the value of the 'EXTNAME' Card (or "PRIMARY" if none)
    19  func (hdu *PrimaryHDU) Name() string {
    20  	card := hdu.header.Get("EXTNAME")
    21  	if card == nil {
    22  		return "PRIMARY"
    23  	}
    24  	return card.Value.(string)
    25  }
    26  
    27  // Version returns the value of the 'EXTVER' Card (or 1 if none)
    28  func (hdu *PrimaryHDU) Version() int {
    29  	card := hdu.header.Get("EXTVER")
    30  	if card == nil {
    31  		return 1
    32  	}
    33  	rv := reflect.ValueOf(card.Value)
    34  	return int(rv.Int())
    35  }
    36  
    37  // newPrimaryHDU returns a new PrimaryHDU attached to file f.
    38  func newPrimaryHDU(f *File, hdr Header) (HDU, error) {
    39  	var err error
    40  	hdu := &PrimaryHDU{
    41  		ImageHDU{
    42  			f:      f,
    43  			header: hdr,
    44  		},
    45  	}
    46  	return hdu, err
    47  }
    48  
    49  // NewPrimaryHDU creates a new PrimaryHDU with Header hdr in File f.
    50  // It returns an error if f already has a Primary HDU.
    51  func NewPrimaryHDU(f *File, hdr Header) (HDU, error) {
    52  	var err error
    53  
    54  	naxes := len(hdr.axes)
    55  	c_naxes := C.int(naxes)
    56  	slice := (*reflect.SliceHeader)((unsafe.Pointer(&hdr.axes)))
    57  	c_axes := (*C.long)(unsafe.Pointer(slice.Data))
    58  	c_status := C.int(0)
    59  
    60  	C.fits_create_img(f.c, C.int(hdr.bitpix), c_naxes, c_axes, &c_status)
    61  	if c_status > 0 {
    62  		return nil, to_err(c_status)
    63  	}
    64  
    65  	for icard := range hdr.slice {
    66  		card := &hdr.slice[icard]
    67  		c_name := C.CString(card.Name)
    68  		defer C.free(unsafe.Pointer(c_name))
    69  		c_type := C.int(0)
    70  		c_status := C.int(0)
    71  		c_comm := C.CString(card.Comment)
    72  		defer C.free(unsafe.Pointer(c_comm))
    73  		var c_ptr unsafe.Pointer
    74  
    75  		switch v := card.Value.(type) {
    76  		case bool:
    77  			c_type = C.TLOGICAL
    78  			c_value := C.char(0) // 'F'
    79  			if v {
    80  				c_value = 1 // 'T'
    81  			}
    82  			c_ptr = unsafe.Pointer(&c_value)
    83  
    84  		case byte:
    85  			c_type = C.TBYTE
    86  			c_ptr = unsafe.Pointer(&v)
    87  
    88  		case uint16:
    89  			c_type = C.TUSHORT
    90  			c_ptr = unsafe.Pointer(&v)
    91  
    92  		case uint32:
    93  			c_type = C.TUINT
    94  			c_ptr = unsafe.Pointer(&v)
    95  
    96  		case uint64:
    97  			c_type = C.TULONG
    98  			c_ptr = unsafe.Pointer(&v)
    99  
   100  		case uint:
   101  			c_type = C.TULONG
   102  			c_value := C.ulong(v)
   103  			c_ptr = unsafe.Pointer(&c_value)
   104  
   105  		case int8:
   106  			c_type = C.TSBYTE
   107  			c_ptr = unsafe.Pointer(&v)
   108  
   109  		case int16:
   110  			c_type = C.TSHORT
   111  			c_ptr = unsafe.Pointer(&v)
   112  
   113  		case int32:
   114  			c_type = C.TINT
   115  			c_ptr = unsafe.Pointer(&v)
   116  
   117  		case int64:
   118  			c_type = C.TLONG
   119  			c_ptr = unsafe.Pointer(&v)
   120  
   121  		case int:
   122  			c_type = C.TLONG
   123  			c_value := C.long(v)
   124  			c_ptr = unsafe.Pointer(&c_value)
   125  
   126  		case float32:
   127  			c_type = C.TFLOAT
   128  			c_ptr = unsafe.Pointer(&v)
   129  
   130  		case float64:
   131  			c_type = C.TDOUBLE
   132  			c_ptr = unsafe.Pointer(&v)
   133  
   134  		case complex64:
   135  			c_type = C.TCOMPLEX
   136  			c_ptr = unsafe.Pointer(&v) // FIXME: assumes same memory layout than C
   137  
   138  		case complex128:
   139  			c_type = C.TDBLCOMPLEX
   140  			c_ptr = unsafe.Pointer(&v) // FIXME: assumes same memory layout than C
   141  
   142  		case string:
   143  			c_type = C.TSTRING
   144  			c_value := C.CString(v)
   145  			defer C.free(unsafe.Pointer(c_value))
   146  			c_ptr = unsafe.Pointer(c_value)
   147  
   148  		default:
   149  			panic(fmt.Errorf("cfitsio: invalid card type (%T)", v))
   150  		}
   151  
   152  		C.fits_update_key(f.c, c_type, c_name, c_ptr, c_comm, &c_status)
   153  
   154  		if c_status > 0 {
   155  			return nil, to_err(c_status)
   156  		}
   157  	}
   158  
   159  	if len(f.hdus) > 0 {
   160  		return nil, fmt.Errorf("cfitsio: File has already a Primary HDU")
   161  	}
   162  
   163  	hdu, err := f.readHDU(0)
   164  	if err != nil {
   165  		return nil, err
   166  	}
   167  	f.hdus = append(f.hdus, hdu)
   168  
   169  	return hdu, err
   170  }
   171  
   172  // EOF