예제 #1
0
void configure_compression(fitsfile* fileptr, PyObject* header) {
    /* Configure the compression-related elements in the fitsfile struct
       using values in the FITS header. */

    FITSfile* Fptr;

    int tfields;
    tcolumn* columns;

    char keyword[9];
    char* zname;
    int znaxis;
    char* tmp;
    float version;

    unsigned int idx;

    Fptr = fileptr->Fptr;
    tfields = Fptr->tfield;
    columns = Fptr->tableptr;

    // Get the ZBITPIX header value; if this is missing we're in trouble
    if (0 != get_header_int(header, "ZBITPIX", &(Fptr->zbitpix), 0)) {
        return;
    }

    // By default assume there is no ZBLANK column and check for ZBLANK or
    // BLANK in the header
    Fptr->cn_zblank = Fptr->cn_zzero = Fptr->cn_zscale = -1;
    Fptr->cn_uncompressed = 0;
#ifdef CFITSIO_SUPPORTS_GZIPDATA
    Fptr->cn_gzip_data = 0;
#endif

    // Check for a ZBLANK, ZZERO, ZSCALE, and
    // UNCOMPRESSED_DATA/GZIP_COMPRESSED_DATA columns in the compressed data
    // table
    for (idx = 0; idx < tfields; idx++) {
        if (0 == strncmp(columns[idx].ttype, "UNCOMPRESSED_DATA", 18)) {
            Fptr->cn_uncompressed = idx + 1;
#ifdef CFITSIO_SUPPORTS_GZIPDATA
        } else if (0 == strncmp(columns[idx].ttype,
                                "GZIP_COMPRESSED_DATA", 21)) {
            Fptr->cn_gzip_data = idx + 1;
#endif
        } else if (0 == strncmp(columns[idx].ttype, "ZSCALE", 7)) {
            Fptr->cn_zscale = idx + 1;
        } else if (0 == strncmp(columns[idx].ttype, "ZZERO", 6)) {
            Fptr->cn_zzero = idx + 1;
        } else if (0 == strncmp(columns[idx].ttype, "ZBLANK", 7)) {
            Fptr->cn_zblank = idx + 1;
        }
    }

    Fptr->zblank = 0;
    if (Fptr->cn_zblank < 1) {
        // No ZBLANK column--check the ZBLANK and BLANK heard keywords
        if(0 != get_header_int(header, "ZBLANK", &(Fptr->zblank), 0)) {
            // ZBLANK keyword not found
            get_header_int(header, "BLANK", &(Fptr->zblank), 0);
        }
    }

    Fptr->zscale = 1.0;
    if (Fptr->cn_zscale < 1) {
        if (0 != get_header_double(header, "ZSCALE", &(Fptr->zscale), 1.0)) {
            Fptr->cn_zscale = 0;
        }
    }
    Fptr->cn_bscale = Fptr->zscale;

    Fptr->zzero = 0.0;
    if (Fptr->cn_zzero < 1) {
        if (0 != get_header_double(header, "ZZERO", &(Fptr->zzero), 0.0)) {
            Fptr->cn_zzero = 0;
        }
    }
    Fptr->cn_bzero = Fptr->zzero;

    get_header_string(header, "ZCMPTYPE", &tmp, DEFAULT_COMPRESSION_TYPE);
    strncpy(Fptr->zcmptype, tmp, 11);
    Fptr->zcmptype[strlen(tmp)] = '\0';

    Fptr->compress_type = compress_type_from_string(Fptr->zcmptype);
    if (PyErr_Occurred()) {
        return;
    }

    get_header_int(header, "ZNAXIS", &znaxis, 0);
    Fptr->zndim = znaxis;

    if (znaxis > MAX_COMPRESS_DIM) {
        // The CFITSIO compression code currently only supports up to 6
        // dimensions by default.
        znaxis = MAX_COMPRESS_DIM;
    }

    Fptr->maxtilelen = 1;
    for (idx = 1; idx <= znaxis; idx++) {
        snprintf(keyword, 9, "ZNAXIS%u", idx);
        get_header_long(header, keyword, Fptr->znaxis + idx - 1, 0);
        snprintf(keyword, 9, "ZTILE%u", idx);
        get_header_long(header, keyword, Fptr->tilesize + idx - 1, 0);
        Fptr->maxtilelen *= Fptr->tilesize[idx - 1];
    }

    // Set some more default compression options
    Fptr->rice_blocksize = DEFAULT_BLOCK_SIZE;
    Fptr->rice_bytepix = DEFAULT_BYTE_PIX;
    Fptr->quantize_level = DEFAULT_QUANTIZE_LEVEL;
    Fptr->hcomp_smooth = DEFAULT_HCOMP_SMOOTH;
    Fptr->hcomp_scale = DEFAULT_HCOMP_SCALE;

    // Now process the ZVALn keywords
    idx = 1;
    while (1) {
        snprintf(keyword, 9, "ZNAME%u", idx);
        // Assumes there are no gaps in the ZNAMEn keywords; this same
        // assumption was made in the Python code.  This could be done slightly
        // more flexibly by using a wildcard slice of the header
        if (0 != get_header_string(header, keyword, &zname, "")) {
            break;
        }
        snprintf(keyword, 9, "ZVAL%u", idx);
        if (Fptr->compress_type == RICE_1) {
            if (0 == strcmp(zname, "BLOCKSIZE")) {
                get_header_int(header, keyword, &(Fptr->rice_blocksize),
                               DEFAULT_BLOCK_SIZE);
            } else if (0 == strcmp(zname, "BYTEPIX")) {
                get_header_int(header, keyword, &(Fptr->rice_bytepix),
                               DEFAULT_BYTE_PIX);
            }
        } else if (Fptr->compress_type == HCOMPRESS_1) {
            if (0 == strcmp(zname, "SMOOTH")) {
                get_header_int(header, keyword, &(Fptr->hcomp_smooth),
                               DEFAULT_HCOMP_SMOOTH);
            } else if (0 == strcmp(zname, "SCALE")) {
                get_header_float(header, keyword, &(Fptr->hcomp_scale),
                                 DEFAULT_HCOMP_SCALE);
            }
        } else if (Fptr->zbitpix < 0 && 0 == strcmp(zname, "NOISEBIT")) {
             get_header_float(header, keyword, &(Fptr->quantize_level),
                              DEFAULT_QUANTIZE_LEVEL);
             if (Fptr->quantize_level == 0.0) {
                 /* NOISEBIT == 0 is equivalent to no quantize */
                 Fptr->quantize_level = NO_QUANTIZE;
             }
        }

        idx++;
    }

    /* The ZQUANTIZ keyword determines the quantization algorithm; NO_QUANTIZE
       implies lossless compression */
    if (0 == get_header_string(header, "ZQUANTIZ", &tmp, "")) {
        /* Ugh; the fact that cfitsio defines its version as a float makes
           preprocessor comparison impossible */
        fits_get_version(&version);
        if ((version >= CFITSIO_LOSSLESS_COMP_SUPPORTED_VERS) &&
                (0 == strcmp(tmp, "NONE"))) {
            Fptr->quantize_level = NO_QUANTIZE;
        } else if (0 == strcmp(tmp, "SUBTRACTIVE_DITHER_1")) {
#ifdef CFITSIO_SUPPORTS_SUBTRACTIVE_DITHER_2
            // Added in CFITSIO 3.35, this also changed the name of the
            // quantize_dither struct member to quantize_method
            Fptr->quantize_method = SUBTRACTIVE_DITHER_1;
        } else if (0 == strcmp(tmp, "SUBTRACTIVE_DITHER_2")) {
            Fptr->quantize_method = SUBTRACTIVE_DITHER_2;
        } else {
            Fptr->quantize_method = NO_DITHER;
        }
    } else {
        Fptr->quantize_method = NO_DITHER;
    }

    if (Fptr->quantize_method != NO_DITHER) {
        if (0 != get_header_int(header, "ZDITHER0", &(Fptr->dither_seed), 0)) {
            // ZDITHER0 keyword not found
            Fptr->dither_seed = 0;
            Fptr->request_dither_seed = 0;
        }
    }
#else
            Fptr->quantize_dither = SUBTRACTIVE_DITHER_1;
        } else {
예제 #2
0
void tcolumns_from_header(fitsfile* fileptr, PyObject* header,
                          tcolumn** columns) {
    // Creates the array of tcolumn structures from the table column keywords
    // read from the astropy.io.fits.Header object; caller is responsible for
    // freeing the memory allocated for this array

    tcolumn* column;
    char tkw[9];

    int tfields;
    char ttype[72];
    char tform[72];
    int dtcode;
    long trepeat;
    long twidth;
    long long totalwidth;
    int status = 0;
    int idx;

    if (get_header_int(header, "TFIELDS", &tfields, 0, HDR_FAIL_VAL_NEGATIVE) == GET_HEADER_FAILED) {
        return;
    }
    /* To avoid issues in the loop we need to limit the number of TFIELDs to
       999. Otherwise we would exceed the maximum length of the keyword name of
       8. This could lead to multiple accesses of the same header keyword with
       snprintf because we limit it to 8 characters + null-termination. */
    if (tfields > 999) {
        PyErr_SetString(PyExc_ValueError, "The TFIELDS value exceeds 999.");
        return;
    }

    // This used to use PyMem_New, but don't do that; CFITSIO will later
    // free() this object when the file is closed, so just use malloc here
    // *columns = column = PyMem_New(tcolumn, (size_t) tfields);
    *columns = column = calloc((size_t) tfields, sizeof(tcolumn));
    if (column == NULL) {
        PyErr_SetString(PyExc_MemoryError,
                        "Couldn't allocate memory for columns.");
        return;
    }


    for (idx = 1; idx <= tfields; idx++, column++) {
        /* set some invalid defaults */
        column->ttype[0] = '\0';
        column->tbcol = 0;
        column->tdatatype = -9999; /* this default used by cfitsio */
        column->trepeat = 1;
        column->strnull[0] = '\0';
        column->tform[0] = '\0';
        column->twidth = 0;

        snprintf(tkw, 9, "TTYPE%u", idx);
        if (get_header_string(header, tkw, ttype, "", HDR_NOFLAG) == GET_HEADER_FAILED) {
            return;
        }
        strncpy(column->ttype, ttype, 69);
        column->ttype[69] = '\0';

        snprintf(tkw, 9, "TFORM%u", idx);
        if (get_header_string(header, tkw, tform, "", HDR_NOFLAG) == GET_HEADER_FAILED) {
            return;
        }
        strncpy(column->tform, tform, 9);
        column->tform[9] = '\0';
        fits_binary_tform(tform, &dtcode, &trepeat, &twidth, &status);
        if (status != 0) {
            process_status_err(status);
            return;
        }

        column->tdatatype = dtcode;
        column->trepeat = trepeat;
        column->twidth = twidth;

        snprintf(tkw, 9, "TSCAL%u", idx);
        if (get_header_double(header, tkw, &(column->tscale), 1.0, HDR_NOFLAG) == GET_HEADER_FAILED) {
            return;
        }

        snprintf(tkw, 9, "TZERO%u", idx);
        if (get_header_double(header, tkw, &(column->tzero), 0.0, HDR_NOFLAG) == GET_HEADER_FAILED) {
            return;
        }

        snprintf(tkw, 9, "TNULL%u", idx);
        if (get_header_longlong(header, tkw, &(column->tnull), NULL_UNDEFINED, HDR_NOFLAG) == GET_HEADER_FAILED) {
            return;
        }
    }

    fileptr->Fptr->tableptr = *columns;
    fileptr->Fptr->tfield = tfields;

    // This routine from CFITSIO calculates the byte offset of each column
    // and stores it in the column->tbcol field
    ffgtbc(fileptr, &totalwidth, &status);
    if (status != 0) {
        process_status_err(status);
    }

    return;
}
예제 #3
0
void tcolumns_from_header(fitsfile* fileptr, PyObject* header,
                          tcolumn** columns) {
    // Creates the array of tcolumn structures from the table column keywords
    // read from the astropy.io.fits.Header object; caller is responsible for
    // freeing the memory allocated for this array

    tcolumn* column;
    char tkw[9];
    unsigned int idx;

    int tfields;
    char* ttype;
    char* tform;
    int dtcode;
    long trepeat;
    long twidth;
    long long totalwidth;
    int status = 0;

    get_header_int(header, "TFIELDS", &tfields, 0);

    *columns = column = PyMem_New(tcolumn, (size_t) tfields);
    if (column == NULL) {
        return;
    }


    for (idx = 1; idx <= tfields; idx++, column++) {
        /* set some invalid defaults */
        column->ttype[0] = '\0';
        column->tbcol = 0;
        column->tdatatype = -9999; /* this default used by cfitsio */
        column->trepeat = 1;
        column->strnull[0] = '\0';
        column->tform[0] = '\0';
        column->twidth = 0;

        snprintf(tkw, 9, "TTYPE%u", idx);
        get_header_string(header, tkw, &ttype, "");
        strncpy(column->ttype, ttype, 69);
        column->ttype[69] = '\0';

        snprintf(tkw, 9, "TFORM%u", idx);
        get_header_string(header, tkw, &tform, "");
        strncpy(column->tform, tform, 9);
        column->tform[9] = '\0';
        fits_binary_tform(tform, &dtcode, &trepeat, &twidth, &status);
        if (status != 0) {
            process_status_err(status);
            return;
        }

        column->tdatatype = dtcode;
        column->trepeat = trepeat;
        column->twidth = twidth;

        snprintf(tkw, 9, "TSCAL%u", idx);
        get_header_double(header, tkw, &(column->tscale), 1.0);

        snprintf(tkw, 9, "TZERO%u", idx);
        get_header_double(header, tkw, &(column->tzero), 0.0);

        snprintf(tkw, 9, "TNULL%u", idx);
        get_header_longlong(header, tkw, &(column->tnull), NULL_UNDEFINED);
    }

    fileptr->Fptr->tableptr = *columns;
    fileptr->Fptr->tfield = tfields;

    // This routine from CFITSIO calculates the byte offset of each column
    // and stores it in the column->tbcol field
    ffgtbc(fileptr, &totalwidth, &status);
    if (status != 0) {
        process_status_err(status);
    }

    return;
}
예제 #4
0
파일: win32_net.c 프로젝트: 5py/libmpg123
int win32_net_http_open(char* url, struct httpdata *hd)
{
	mpg123_string purl, host, port, path;
	mpg123_string request, response, request_url;
	mpg123_string httpauth1;
	ws.local_socket = SOCKET_ERROR;
	int oom  = 0;
	int relocate, numrelocs = 0;
	int got_location = FALSE;
	/*
		workaround for http://www.global24music.com/rautemusik/files/extreme/isdn.pls
		this site's apache gives me a relocation to the same place when I give the port in Host request field
		for the record: Apache/2.0.51 (Fedora)
	*/
	int try_without_port = 0;
	mpg123_init_string(&purl);
	mpg123_init_string(&host);
	mpg123_init_string(&port);
	mpg123_init_string(&path);
	mpg123_init_string(&request);
	mpg123_init_string(&response);
	mpg123_init_string(&request_url);
	mpg123_init_string(&httpauth1);

	/* Get initial info for proxy server. Once. */
	if(hd->proxystate == PROXY_UNKNOWN && !proxy_init(hd)) goto exit;

	if(!translate_url(url, &purl)){ oom=1; goto exit; }

	/* Don't confuse the different auth strings... */
	if(!split_url(&purl, &httpauth1, NULL, NULL, NULL) ){ oom=1; goto exit; }

	/* "GET http://"		11
	 * " HTTP/1.0\r\nUser-Agent: <PACKAGE_NAME>/<PACKAGE_VERSION>\r\n"
	 * 				26 + PACKAGE_NAME + PACKAGE_VERSION
	 * accept header            + accept_length()
	 * "Authorization: Basic \r\n"	23
	 * "\r\n"			 2
	 * ... plus the other predefined header lines
	 */
	/* Just use this estimate as first guess to reduce malloc calls in string library. */
	{
		size_t length_estimate = 62 + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION) 
		                       + accept_length() + strlen(CONN_HEAD) + strlen(icy_yes) + purl.fill;
		if(    !mpg123_grow_string(&request, length_estimate)
		    || !mpg123_grow_string(&response,4096) )
		{
			oom=1; goto exit;
		}
	}

	do
	{
		/* Storing the request url, with http:// prepended if needed. */
		/* used to be url here... seemed wrong to me (when loop advanced...) */
		if(strncasecmp(purl.p, "http://", 7) != 0) mpg123_set_string(&request_url, "http://");
		else mpg123_set_string(&request_url, "");

		mpg123_add_string(&request_url, purl.p);

		if (hd->proxystate >= PROXY_HOST)
		{
			/* We will connect to proxy, full URL goes into the request. */
			if(    !mpg123_copy_string(&hd->proxyhost, &host)
			    || !mpg123_copy_string(&hd->proxyport, &port)
			    || !mpg123_set_string(&request, "GET ")
			    || !mpg123_add_string(&request, request_url.p) )
			{
				oom=1; goto exit;
			}
		}
		else
		{
			/* We will connect to the host from the URL and only the path goes into the request. */
			if(!split_url(&purl, NULL, &host, &port, &path)){ oom=1; goto exit; }
			if(    !mpg123_set_string(&request, "GET ")
			    || !mpg123_add_string(&request, path.p) )
			{
				oom=1; goto exit;
			}
		}

		if(!fill_request(&request, &host, &port, &httpauth1, &try_without_port)){ oom=1; goto exit; }

		httpauth1.fill = 0; /* We use the auth data from the URL only once. */
		debug2("attempting to open_connection to %s:%s", host.p, port.p);
		win32_net_open_connection(&host, &port);
		if(ws.local_socket == SOCKET_ERROR)
		{
			error1("Unable to establish connection to %s", host.fill ? host.p : "");
			goto exit;
		}
		debug("win32_net_open_connection succeed");
#define http_failure win32_net_close(ws.local_socket); ws.local_socket=SOCKET_ERROR; goto exit;
		
		if(param.verbose > 2) fprintf(stderr, "HTTP request:\n%s\n",request.p);
		if(!win32_net_writestring(ws.local_socket, &request)){ http_failure; }
		debug("Skipping fdopen for WSA sockets");
		relocate = FALSE;
		/* Arbitrary length limit here... */
#define safe_readstring \
		win32_net_readstring(&response, SIZE_MAX/16, NULL); \
		if(response.fill > SIZE_MAX/16) /* > because of appended zero. */ \
		{ \
			error("HTTP response line exceeds max. length"); \
			http_failure; \
		} \
		else if(response.fill == 0) \
		{ \
			error("readstring failed"); \
			http_failure; \
		} \
		if(param.verbose > 2) fprintf(stderr, "HTTP in: %s", response.p);
		safe_readstring;

		{
			char *sptr;
			if((sptr = strchr(response.p, ' ')))
			{
				if(response.fill > sptr-response.p+2)
				switch (sptr[1])
				{
					case '3':
						relocate = TRUE;
					case '2':
						break;
					default:
						fprintf (stderr, "HTTP request failed: %s", sptr+1); /* '\n' is included */
						http_failure;
				}
				else{ error("Too short response,"); http_failure; }
			}
		}

		/* If we are relocated, we need to look out for a Location header. */
		got_location = FALSE;

		do
		{
			safe_readstring; /* Think about that: Should we really error out when we get nothing? Could be that the server forgot the trailing empty line... */
			if (!strncasecmp(response.p, "Location: ", 10))
			{ /* It is a redirection! */
				if(!win32_net_resolve_redirect(&response, &request_url, &purl)){ oom=1, http_failure; }

				if(!strcmp(purl.p, request_url.p))
				{
					warning("relocated to very same place! trying request again without host port");
					try_without_port = 1;
				}
				got_location = TRUE;
			}
			else
			{ /* We got a header line (or the closing empty line). */
				char *tmp;
				debug1("searching for header values... %s", response.p);
				/* Not sure if I want to bail out on error here. */
				/* Also: What text encoding are these strings in? Doesn't need to be plain ASCII... */
				get_header_string(&response, "content-type", &hd->content_type);
				get_header_string(&response, "icy-name",     &hd->icy_name);
				get_header_string(&response, "icy-url",      &hd->icy_url);

				/* watch out for icy-metaint */
				if((tmp = get_header_val("icy-metaint", &response)))
				{
					hd->icy_interval = (off_t) atol(tmp); /* atoll ? */
					debug1("got icy-metaint %li", (long int)hd->icy_interval);
				}
			}
		} while(response.p[0] != '\r' && response.p[0] != '\n');
	} while(relocate && got_location && purl.fill && numrelocs++ < HTTP_MAX_RELOCATIONS);
	if(relocate)
	{
		if(!got_location)
		error("Server meant to redirect but failed to provide a location!");
		else
		error1("Too many HTTP relocations (%i).", numrelocs);

		http_failure;
	}

exit: /* The end as well as the exception handling point... */
	if(oom) error("Apparently, I ran out of memory or had some bad input data...");

	mpg123_free_string(&purl);
	mpg123_free_string(&host);
	mpg123_free_string(&port);
	mpg123_free_string(&path);
	mpg123_free_string(&request);
	mpg123_free_string(&response);
	mpg123_free_string(&request_url);
	mpg123_free_string(&httpauth1);
	if (ws.local_socket == SOCKET_ERROR || oom)
	return -1;
	else
	return 1;
}