void cache_voxeldata(Tex *tex, int scene_frame) { VoxelData *vd = tex->vd; FILE *fp; int curframe; char path[sizeof(vd->source_path)]; /* only re-cache if dataset needs updating */ if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == scene_frame)) if (vd->ok) return; /* clear out old cache, ready for new */ if (vd->dataset) { MEM_freeN(vd->dataset); vd->dataset = NULL; } /* reset data_type */ vd->data_type = TEX_VD_INTENSITY; if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; else curframe = scene_frame; BLI_strncpy(path, vd->source_path, sizeof(path)); /* each type is responsible for setting to true */ vd->ok = false; switch (vd->file_format) { case TEX_VD_IMAGE_SEQUENCE: load_frame_image_sequence(vd, tex); return; case TEX_VD_SMOKE: init_frame_smoke(vd, scene_frame); return; case TEX_VD_HAIR: init_frame_hair(vd, scene_frame); return; case TEX_VD_BLENDERVOXEL: BLI_path_abs(path, G.main->name); fp = BLI_fopen(path, "rb"); if (!fp) return; if (read_voxeldata_header(fp, vd)) load_frame_blendervoxel(vd, fp, curframe - 1); fclose(fp); return; case TEX_VD_RAW_8BIT: BLI_path_abs(path, G.main->name); fp = BLI_fopen(path, "rb"); if (!fp) return; load_frame_raw8(vd, fp, curframe); fclose(fp); return; } }
static int save_stdjpeg(const char *name, struct ImBuf *ibuf) { FILE *outfile; struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; struct my_error_mgr jerr; if ((outfile = BLI_fopen(name, "wb")) == NULL) return 0; cinfo->err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = jpeg_error; /* Establish the setjmp return context for jpeg_error to use. */ if (setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_compress(cinfo); fclose(outfile); remove(name); return 0; } init_jpeg(outfile, cinfo, ibuf); write_jpeg(cinfo, ibuf); fclose(outfile); jpeg_destroy_compress(cinfo); return 1; }
static opj_stream_t *opj_stream_create_from_file(const char *filepath, OPJ_UINT32 p_size, OPJ_BOOL p_is_read_stream, FILE **r_file) { FILE *p_file = BLI_fopen(filepath, p_is_read_stream ? "rb" : "wb"); if (p_file == NULL) { return NULL; } opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream); if (l_stream == NULL) { fclose(p_file); return NULL; } opj_stream_set_user_data(l_stream, p_file, opj_free_from_file); opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file)); opj_stream_set_write_function(l_stream, opj_write_from_file); opj_stream_set_read_function(l_stream, opj_read_from_file); opj_stream_set_skip_function(l_stream, opj_skip_from_file); opj_stream_set_seek_function(l_stream, opj_seek_from_file); if (r_file) { *r_file = p_file; } return l_stream; }
void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size) { FILE *fp = BLI_fopen(filepath, "rb"); void *mem = NULL; if (fp) { fseek(fp, 0L, SEEK_END); const long int filelen = ftell(fp); if (filelen == -1) { goto finally; } fseek(fp, 0L, SEEK_SET); mem = MEM_mallocN(filelen + pad_bytes, __func__); if (mem == NULL) { goto finally; } const long int filelen_read = fread(mem, 1, filelen, fp); if ((filelen_read != filelen) || ferror(fp)) { MEM_freeN(mem); mem = NULL; goto finally; } *r_size = filelen_read; finally: fclose(fp); } return mem; }
int imb_savehdr(struct ImBuf *ibuf, const char *name, int flags) { FILE *file = BLI_fopen(name, "wb"); float *fp = NULL; int y, width = ibuf->x, height = ibuf->y; unsigned char *cp = NULL; (void)flags; /* unused */ if (file == NULL) return 0; writeHeader(file, width, height); if (ibuf->rect) cp = (unsigned char *)ibuf->rect + ibuf->channels * (height - 1) * width; if (ibuf->rect_float) fp = ibuf->rect_float + ibuf->channels * (height - 1) * width; for (y = height - 1; y >= 0; y--) { if (fwritecolrs(file, width, ibuf->channels, cp, fp) < 0) { fclose(file); printf("HDR write error\n"); return 0; } if (cp) cp -= ibuf->channels * width; if (fp) fp -= ibuf->channels * width; } fclose(file); return 1; }
anim_index_builder *IMB_index_builder_create(const char *name) { anim_index_builder *rv = MEM_callocN(sizeof(struct anim_index_builder), "index builder"); fprintf(stderr, "Starting work on index: %s\n", name); BLI_strncpy(rv->name, name, sizeof(rv->name)); BLI_strncpy(rv->temp_name, name, sizeof(rv->temp_name)); strcat(rv->temp_name, temp_ext); BLI_make_existing_file(rv->temp_name); rv->fp = BLI_fopen(rv->temp_name, "wb"); if (!rv->fp) { fprintf(stderr, "Couldn't open index target: %s! " "Index build broken!\n", rv->temp_name); MEM_freeN(rv); return NULL; } fprintf(rv->fp, "%s%c%.3d", magic, (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v', INDEX_FILE_VERSION); return rv; }
/** * Creates the file with nothing in it, or updates its last-modified date if it already exists. * Returns true if successful. (like the unix touch command) */ bool BLI_file_touch(const char *file) { FILE *f = BLI_fopen(file, "r+b"); if (f != NULL) { int c = getc(f); rewind(f); putc(c, f); } else { f = BLI_fopen(file, "wb"); } if (f) { fclose(f); return true; } return false; }
static void write_history(void) { struct RecentFile *recent, *next_recent; char name[FILE_MAX]; const char *user_config_dir; FILE *fp; int i; /* no write history for recovered startup files */ if (G.main->name[0] == 0) return; /* will be NULL in background mode */ user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL); if (!user_config_dir) return; BLI_make_file_string("/", name, user_config_dir, BLENDER_HISTORY_FILE); recent = G.recent_files.first; /* refresh recent-files.txt of recent opened files, when current file was changed */ if (!(recent) || (BLI_path_cmp(recent->filepath, G.main->name) != 0)) { fp = BLI_fopen(name, "w"); if (fp) { /* add current file to the beginning of list */ recent = (RecentFile *)MEM_mallocN(sizeof(RecentFile), "RecentFile"); recent->filepath = BLI_strdup(G.main->name); BLI_addhead(&(G.recent_files), recent); /* write current file to recent-files.txt */ fprintf(fp, "%s\n", recent->filepath); recent = recent->next; i = 1; /* write rest of recent opened files to recent-files.txt */ while ((i < U.recent_files) && (recent)) { /* this prevents to have duplicities in list */ if (BLI_path_cmp(recent->filepath, G.main->name) != 0) { fprintf(fp, "%s\n", recent->filepath); recent = recent->next; } else { next_recent = recent->next; MEM_freeN(recent->filepath); BLI_freelinkN(&(G.recent_files), recent); recent = next_recent; } i++; } fclose(fp); } /* also update most recent files on System */ GHOST_addToSystemRecentFiles(G.main->name); } }
bool MOD_meshcache_read_mdd_times(const char *filepath, float (*vertexCos)[3], const int verts_tot, const char interp, const float time, const float fps, const char time_mode, const char **err_str) { float frame; FILE *fp = BLI_fopen(filepath, "rb"); bool ok; if (fp == NULL) { *err_str = errno ? strerror(errno) : "Unknown error opening file"; return false; } switch (time_mode) { case MOD_MESHCACHE_TIME_FRAME: { frame = time; break; } case MOD_MESHCACHE_TIME_SECONDS: { /* we need to find the closest time */ if (meshcache_read_mdd_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) { fclose(fp); return false; } rewind(fp); break; } case MOD_MESHCACHE_TIME_FACTOR: default: { MDDHead mdd_head; if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) { fclose(fp); return false; } frame = CLAMPIS(time, 0.0f, 1.0f) * (float)mdd_head.frame_tot; rewind(fp); break; } } ok = MOD_meshcache_read_mdd_frame(fp, vertexCos, verts_tot, interp, frame, err_str); fclose(fp); return ok; }
/** * Reads the contents of a text file and returns the lines in a linked list. */ LinkNode *BLI_file_read_as_lines(const char *name) { FILE *fp = BLI_fopen(name, "r"); LinkNodePair lines = {NULL, NULL}; char *buf; size_t size; if (!fp) return NULL; fseek(fp, 0, SEEK_END); size = (size_t)ftell(fp); fseek(fp, 0, SEEK_SET); if (UNLIKELY(size == (size_t)-1)) { fclose(fp); return NULL; } buf = MEM_mallocN(size, "file_as_lines"); if (buf) { size_t i, last = 0; /* * size = because on win32 reading * all the bytes in the file will return * less bytes because of crnl changes. */ size = fread(buf, 1, size, fp); for (i = 0; i <= size; i++) { if (i == size || buf[i] == '\n') { char *line = BLI_strdupn(&buf[last], i - last); BLI_linklist_append(&lines, line); /* faster to build singly-linked list in reverse order */ /* alternatively, could process buffer in reverse order so * list ends up right way round to start with */ last = i + 1; } } MEM_freeN(buf); } fclose(fp); return lines.list; }
bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header) { FILE *fp; errno = 0; fp = BLI_fopen(filepath, "wb"); if (fp == NULL) { fprintf(stderr, "Unable to save '%s': %s\n", filepath, errno ? strerror(errno) : "Unknown error opening file"); return false; } BKE_report_write_file_fp(fp, reports, header); fclose(fp); return true; }
/** * Reads the contents of a text file and returns the lines in a linked list. */ LinkNode *BLI_file_read_as_lines(const char *name) { FILE *fp = BLI_fopen(name, "r"); LinkNodePair lines = {NULL, NULL}; char *buf; size_t size; if (!fp) return NULL; fseek(fp, 0, SEEK_END); size = (size_t)ftell(fp); fseek(fp, 0, SEEK_SET); if (UNLIKELY(size == (size_t)-1)) { fclose(fp); return NULL; } buf = MEM_mallocN(size, "file_as_lines"); if (buf) { size_t i, last = 0; /* * size = because on win32 reading * all the bytes in the file will return * less bytes because of `CRNL` changes. */ size = fread(buf, 1, size, fp); for (i = 0; i <= size; i++) { if (i == size || buf[i] == '\n') { char *line = BLI_strdupn(&buf[last], i - last); BLI_linklist_append(&lines, line); last = i + 1; } } MEM_freeN(buf); } fclose(fp); return lines.list; }
/** * Write #BLENDER_HISTORY_FILE as-is, without checking the environment * (thats handled by #wm_history_file_update). */ static void wm_history_file_write(void) { const char *user_config_dir; char name[FILE_MAX]; FILE *fp; /* will be NULL in background mode */ user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL); if (!user_config_dir) return; BLI_make_file_string("/", name, user_config_dir, BLENDER_HISTORY_FILE); fp = BLI_fopen(name, "w"); if (fp) { struct RecentFile *recent; for (recent = G.recent_files.first; recent; recent = recent->next) { fprintf(fp, "%s\n", recent->filepath); } fclose(fp); } }
struct anim_index *IMB_indexer_open(const char *name) { char header[13]; struct anim_index *idx; FILE *fp = BLI_fopen(name, "rb"); int i; if (!fp) { return NULL; } if (fread(header, 12, 1, fp) != 1) { fclose(fp); return NULL; } header[12] = 0; if (memcmp(header, magic, 8) != 0) { fclose(fp); return NULL; } if (atoi(header + 9) != INDEX_FILE_VERSION) { fclose(fp); return NULL; } idx = MEM_callocN(sizeof(struct anim_index), "anim_index"); BLI_strncpy(idx->name, name, sizeof(idx->name)); fseek(fp, 0, SEEK_END); idx->num_entries = (ftell(fp) - 12) / (sizeof(int) + /* framepos */ sizeof(unsigned long long) + /* seek_pos */ sizeof(unsigned long long) + /* seek_pos_dts */ sizeof(unsigned long long) /* pts */ ); fseek(fp, 12, SEEK_SET); idx->entries = MEM_callocN(sizeof(struct anim_index_entry) * idx->num_entries, "anim_index_entries"); for (i = 0; i < idx->num_entries; i++) { fread(&idx->entries[i].frameno, sizeof(int), 1, fp); fread(&idx->entries[i].seek_pos, sizeof(unsigned long long), 1, fp); fread(&idx->entries[i].seek_pos_dts, sizeof(unsigned long long), 1, fp); fread(&idx->entries[i].pts, sizeof(unsigned long long), 1, fp); } if (((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V'))) { for (i = 0; i < idx->num_entries; i++) { BLI_endian_switch_int32(&idx->entries[i].frameno); BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos); BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos_dts); BLI_endian_switch_int64((int64_t *)&idx->entries[i].pts); } } fclose(fp); return idx; }
static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetFile, char *debugStrBuffer) { FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim); FluidsimSettings *domainSettings= fluidmd->fss; FILE *fileCfg; int dirExist = 0; char newSurfdataPath[FILE_MAX]; /* modified output settings */ const char *suffixConfigTmp = FLUID_SUFFIX_CONFIG_TMP; int outStringsChanged = 0; /* prepare names... */ const char *relbase= modifier_path_relbase(fsDomain); BLI_strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR); BLI_strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR); /* if 0'd out below, this value is never used! */ BLI_path_abs(targetDir, relbase); /* fixed #frame-no */ /* .tmp: don't overwrite/delete original file */ BLI_join_dirfile(targetFile, FILE_MAX, targetDir, suffixConfigTmp); // make sure all directories exist // as the bobjs use the same dir, this only needs to be checked // for the cfg output BLI_make_existing_file(targetFile); // check selected directory // simply try to open cfg file for writing to test validity of settings fileCfg = BLI_fopen(targetFile, "w"); if (fileCfg) { dirExist = 1; fclose(fileCfg); // remove cfg dummy from directory test BLI_delete(targetFile, false, false); } if (targetDir[0] == '\0' || (!dirExist)) { char blendFile[FILE_MAX]; // invalid dir, reset to current/previous BLI_split_file_part(G.main->name, blendFile, sizeof(blendFile)); BLI_replace_extension(blendFile, FILE_MAX, ""); /* strip .blend */ BLI_snprintf(newSurfdataPath, FILE_MAX, "//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name); BLI_snprintf(debugStrBuffer, 256, "fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath); elbeemDebugOut(debugStrBuffer); outStringsChanged=1; } /* check if modified output dir is ok */ #if 0 if (outStringsChanged) { char dispmsg[FILE_MAX+256]; int selection=0; BLI_strncpy(dispmsg, "Output settings set to: '", sizeof(dispmsg)); strcat(dispmsg, newSurfdataPath); strcat(dispmsg, "'%t|Continue with changed settings %x1|Discard and abort %x0"); /* ask user if thats what he/she wants... */ selection = pupmenu(dispmsg); if (selection < 1) return 0; /* 0 from menu, or -1 aborted */ BLI_strncpy(targetDir, newSurfdataPath, sizeof(targetDir)); strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR); BLI_path_abs(targetDir, G.main->name); /* fixed #frame-no */ } #endif return outStringsChanged; }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ unsigned char* mat_livedb_get_mat_preview(const char *address, int32_t id, unsigned int *width, unsigned int *height, const char *_file_path) { long file_size; int cur_socket; unsigned char *buf = 0, *img_buf = 0; FILE *hFile; char file_path[FILE_MAX]; /* create file path */ snprintf(file_path, FILE_MAX, "%s%d.raw", _file_path, id); hFile = BLI_fopen(file_path, "rb"); if(hFile) { fseek(hFile, 0, SEEK_END); file_size = ftell(hFile); rewind(hFile); img_buf = MEM_mallocN(file_size, "ldb preview"); if(!img_buf) return 0; if(fread(img_buf, file_size, 1, hFile)) *width = *height = (unsigned int)sqrtf(file_size / 4); else { MEM_freeN(img_buf); buf = 0; file_size = 0; } fclose(hFile); } else { img_buf = 0; file_size = 0; } if(!img_buf) { uint32_t buf_size; cur_socket = mat_livedb_connect(address); if(cur_socket < 0) return 0; if(!mat_livedb_request_preview(cur_socket, id)) { mat_livedb_disconnect(cur_socket); return 0; } buf = mat_livedb_receive(cur_socket, GET_LDB_MAT_PREVIEW, &buf_size); mat_livedb_disconnect(cur_socket); if(!buf || !buf_size) { if(buf) MEM_freeN(buf); *width = *height = 0; return 0; } else { *width = ((uint32_t*)buf)[0]; *height = ((uint32_t*)buf)[1]; file_size = *width * *height * 4; img_buf = MEM_mallocN(file_size, "ldb preview"); if(!img_buf) { MEM_freeN(buf); *width = *height = 0; return 0; } memcpy(img_buf, buf + sizeof(uint32_t) * 2, file_size); MEM_freeN(buf); hFile = BLI_fopen(file_path, "wb"); if(hFile) { if(!fwrite(img_buf, file_size, 1, hFile)) { fclose(hFile); MEM_freeN(img_buf); *width = *height = 0; return 0; } fclose(hFile); } else { MEM_freeN(img_buf); *width = *height = 0; return 0; } } } return img_buf; } //mat_livedb_get_mat_preview()
LogImageFile *dpxCreate(const char *filename, int width, int height, int bitsPerSample, int hasAlpha, int isLogarithmic, int referenceWhite, int referenceBlack, float gamma, const char *creator) { DpxMainHeader header; const char *shortFilename = NULL; unsigned char pad[6044]; LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__); if (dpx == NULL) { if (verbose) printf("DPX: Failed to malloc dpx file structure.\n"); return NULL; } dpx->width = width; dpx->height = height; dpx->element[0].bitsPerSample = bitsPerSample; dpx->element[0].dataOffset = 8092; dpx->element[0].maxValue = powf(2, dpx->element[0].bitsPerSample) - 1.0f; dpx->isMSB = 1; dpx->numElements = 1; switch (bitsPerSample) { case 8: case 16: dpx->element[0].packing = 0; break; case 10: case 12: /* Packed Type A padding is the most common 10/12 bits format */ dpx->element[0].packing = 1; break; default: if (verbose) printf("DPX: bitsPerSample not supported: %d\n", bitsPerSample); logImageClose(dpx); return NULL; } if (hasAlpha == 0) { dpx->depth = 3; dpx->element[0].depth = 3; dpx->element[0].descriptor = descriptor_RGB; } else { dpx->depth = 4; dpx->element[0].depth = 4; dpx->element[0].descriptor = descriptor_RGBA; } if (isLogarithmic == 0) { dpx->element[0].transfer = transfer_Linear; dpx->element[0].refHighQuantity = dpx->element[0].maxValue; } else { dpx->element[0].transfer = transfer_PrintingDensity; dpx->element[0].refHighQuantity = 2.048f; } dpx->element[0].refLowQuantity = 0; dpx->element[0].refLowData = 0; dpx->element[0].refHighData = dpx->element[0].maxValue; if (referenceWhite > 0) dpx->referenceWhite = referenceWhite; else dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue; if (referenceBlack > 0) dpx->referenceBlack = referenceBlack; else dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue; if (gamma > 0.0f) dpx->gamma = gamma; else dpx->gamma = 1.7f; shortFilename = strrchr(filename, '/'); if (shortFilename == NULL) shortFilename = filename; else shortFilename++; dpx->file = BLI_fopen(filename, "wb"); if (dpx->file == NULL) { if (verbose) printf("DPX: Couldn't open file %s\n", filename); logImageClose(dpx); return NULL; } fillDpxMainHeader(dpx, &header, shortFilename, creator); if (fwrite(&header, sizeof(header), 1, dpx->file) == 0) { if (verbose) printf("DPX: Couldn't write image header\n"); logImageClose(dpx); return NULL; } /* Header should be rounded to next 8k block * 6044 = 8092 - sizeof(DpxMainHeader) */ memset(&pad, 0, 6044); if (fwrite(&pad, 6044, 1, dpx->file) == 0) { if (verbose) printf("DPX: Couldn't write image header\n"); logImageClose(dpx); return NULL; } return dpx; }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ static MatItem *mat_livedb_add_mat_element(Main *bmain, bContext *C, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, MatItem **_item, char* file_path, float x_pos, float *y_pos) { MatItem *ptr; MatItem *item = *_item; char tex_file_name[1024]; bNodeSocket *sock; switch (item->type) { case MAT_LDB_VALUE_TYPE_EMPTY: { *_item = (MatItem*)((char*)item + item->size); break; } case MAT_LDB_VALUE_TYPE_FLINK: { ptr = (MatItem*) ((char*)item - item->uint_vector[0]); mat_livedb_add_mat_element(bmain, C, ntree, node_to, 0, &ptr, file_path, 0, 0); *_item = (MatItem*)((char*)item + item->size); break; } case MAT_LDB_VALUE_TYPE_NLINK: { bNode *linked_node = *((bNode**) ((MatItem*)((char*)item - item->uint_vector[0]))->data); connect_node(bmain, ntree, linked_node, node_to, sock_to); *_item = (MatItem*)((char*)item + item->size); break; } case MAT_LDB_VALUE_TYPE_NODE: { if(sock_to->type == SOCK_FLOAT && sock_to->default_value && !strcmp(item->data, "ShaderNodeOctFloatTex")) { item = (MatItem*)((char*)item + item->size); ((bNodeSocketValueFloat*)sock_to->default_value)->value = item->float_vector[0]; *_item = (MatItem*)((char*)item + item->size); } else if(sock_to->type == SOCK_RGBA && sock_to->default_value && !strcmp(item->data, "ShaderNodeOctRGBSpectrumTex")) { item = (MatItem*)((char*)item + item->size); ((bNodeSocketValueRGBA*)sock_to->default_value)->value[0] = item->float_vector[0]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[1] = item->float_vector[1]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[2] = item->float_vector[2]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[3] = item->float_vector[3]; *_item = (MatItem*)((char*)item + item->size); } else { float cur_y_pos; int node_height = U.widget_unit; bool childs_present = false; bNode *node_fr = nodeAddNode(C, ntree, item->data); connect_node(bmain, ntree, node_fr, node_to, sock_to); *_item = (MatItem*)((char*)item + item->size); ptr = *_item; *((bNode**)item->data) = node_fr; if(node_fr->type == SH_NODE_OCT_IMAGE_TEX || node_fr->type == SH_NODE_OCT_FLOAT_IMAGE_TEX || node_fr->type == SH_NODE_OCT_ALPHA_IMAGE_TEX) { mat_livedb_add_mat_element(bmain, C, ntree, node_fr, 0, &ptr, file_path, 0, 0); node_height += (U.widget_unit * 2.5); } node_fr->locx = x_pos - node_fr->width - LDB_NODES_H_GAP; node_fr->locy = cur_y_pos = *y_pos; for (sock = node_fr->inputs.first; sock; sock = sock->next) { if(!sock) continue; if(!childs_present) childs_present = true; node_height += U.widget_unit; mat_livedb_add_mat_element(bmain, C, ntree, node_fr, sock, &ptr, file_path, node_fr->locx, &cur_y_pos); } if(node_fr->type == SH_NODE_OCT_GRADIENT_TEX) { mat_livedb_add_mat_element(bmain, C, ntree, node_fr, 0, &ptr, file_path, 0, 0); node_height += (U.widget_unit * 2.5); } *_item = ptr; *y_pos -= (node_height + LDB_NODES_V_GAP); if(childs_present) *y_pos = (*y_pos < cur_y_pos ? *y_pos : cur_y_pos); } break; } case MAT_LDB_VALUE_TYPE_INT: if(sock_to->default_value) ((bNodeSocketValueInt*)sock_to->default_value)->value = item->int_vector[0]; *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_INT2: if(sock_to->default_value) { ((bNodeSocketValueVector*)sock_to->default_value)->value[0] = item->int_vector[0]; ((bNodeSocketValueVector*)sock_to->default_value)->value[1] = item->int_vector[1]; } *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_INT3: if(sock_to->default_value) { ((bNodeSocketValueVector*)sock_to->default_value)->value[0] = item->int_vector[0]; ((bNodeSocketValueVector*)sock_to->default_value)->value[1] = item->int_vector[1]; ((bNodeSocketValueVector*)sock_to->default_value)->value[2] = item->int_vector[2]; } *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_INT4: if(sock_to->default_value) { ((bNodeSocketValueRGBA*)sock_to->default_value)->value[0] = item->int_vector[0]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[1] = item->int_vector[1]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[2] = item->int_vector[2]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[3] = item->int_vector[3]; } *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_FLOAT: if(sock_to->default_value) ((bNodeSocketValueFloat*)sock_to->default_value)->value = item->float_vector[0]; *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_FLOAT2: if(sock_to->default_value) { ((bNodeSocketValueVector*)sock_to->default_value)->value[0] = item->float_vector[0]; ((bNodeSocketValueVector*)sock_to->default_value)->value[1] = item->float_vector[1]; } *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_FLOAT3: if(sock_to->default_value) { ((bNodeSocketValueVector*)sock_to->default_value)->value[0] = item->float_vector[0]; ((bNodeSocketValueVector*)sock_to->default_value)->value[1] = item->float_vector[1]; ((bNodeSocketValueVector*)sock_to->default_value)->value[2] = item->float_vector[2]; } *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_FLOAT4: if(sock_to->default_value) { ((bNodeSocketValueRGBA*)sock_to->default_value)->value[0] = item->float_vector[0]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[1] = item->float_vector[1]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[2] = item->float_vector[2]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[3] = item->float_vector[3]; } *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_BOOL: if(sock_to->default_value) ((bNodeSocketValueBoolean*)sock_to->default_value)->value = item->int_vector[0]; *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_STRING: if(sock_to->default_value) strcpy(((bNodeSocketValueString*)sock_to->default_value)->value, item->data); *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_COLOR: if(sock_to->default_value) { ((bNodeSocketValueRGBA*)sock_to->default_value)->value[0] = item->float_vector[0]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[1] = item->float_vector[1]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[2] = item->float_vector[2]; ((bNodeSocketValueRGBA*)sock_to->default_value)->value[3] = item->float_vector[3]; } *_item = (MatItem*)((char*)item + item->size); break; case MAT_LDB_VALUE_TYPE_FILE: { char* file_name; FILE *file; struct Image *ima = (struct Image*)node_to->id; file_name = item->data + sizeof(uint32_t); if(file_name[0]) { strcpy(tex_file_name, file_path); strcat(tex_file_name, file_name); file = BLI_fopen(tex_file_name, "rb"); if(!file) { file = BLI_fopen(tex_file_name, "wb"); if(file) { if(!fwrite(item->data + sizeof(uint32_t) + strlen(file_name) + 1, *((uint32_t*)item->data), 1, file)) { } fclose(file); } } else fclose(file); } else tex_file_name[0] = 0; if(!ima) node_to->id = (struct ID*)BKE_image_load_exists(tex_file_name); *_item = (MatItem*)((char*)item + item->size); break; } case MAT_LDB_VALUE_TYPE_RAMP: { char* file_name; FILE *file; struct ColorBand *coba = (struct ColorBand*)node_to->storage; RampItem *ramp_item = (RampItem*)item->data; if(coba && ramp_item->pos_cnt > 1) { int i; coba->tot = ramp_item->pos_cnt; for(i = 0; i < ramp_item->pos_cnt; ++i) { coba->data[i].pos = ramp_item->pos_data[i * 4 + 0]; coba->data[i].r = ramp_item->pos_data[i * 4 + 1]; coba->data[i].g = ramp_item->pos_data[i * 4 + 2]; coba->data[i].b = ramp_item->pos_data[i * 4 + 3]; coba->data[i].a = 1.0; } } *_item = (MatItem*)((char*)item + item->size); break; } default: break; } return *_item; } /* mat_livedb_add_mat_element */
CineonFile* cineonOpen(const char* filename) { CineonGenericHeader header; CineonFile* cineon = (CineonFile* )malloc(sizeof(CineonFile)); if (cineon == 0) { if (verbose) d_printf("Failed to malloc cineon file structure.\n"); return 0; } /* for close routine */ cineon->file = 0; cineon->lineBuffer = 0; cineon->pixelBuffer = 0; cineon->membuffer = 0; cineon->memcursor = 0; cineon->membuffersize = 0; cineon->file = BLI_fopen(filename, "rb"); if (cineon->file == 0) { if (verbose) d_printf("Failed to open file \"%s\".\n", filename); cineonClose(cineon); return 0; } cineon->reading = 1; if (logimage_fread(&header, sizeof(CineonGenericHeader), 1, cineon) == 0) { if (verbose) d_printf("Not enough data for header in \"%s\".\n", filename); cineonClose(cineon); return 0; } /* let's assume cineon files are always network order */ if (header.fileInfo.magic_num != ntohl(CINEON_FILE_MAGIC)) { if (verbose) d_printf("Bad magic number %8.8lX in \"%s\".\n", (uintptr_t)ntohl(header.fileInfo.magic_num), filename); cineonClose(cineon); return 0; } if (header.formatInfo.packing != 5) { if (verbose) d_printf("Can't understand packing %d\n", header.formatInfo.packing); cineonClose(cineon); return 0; } cineon->width = ntohl(header.imageInfo.channel[0].pixels_per_line); cineon->height = ntohl(header.imageInfo.channel[0].lines_per_image); cineon->depth = header.imageInfo.channels_per_image; /* cineon->bitsPerPixel = 10; */ cineon->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel; cineon->imageOffset = ntohl(header.fileInfo.image_offset); cineon->lineBufferLength = pixelsToLongs(cineon->width * cineon->depth); cineon->lineBuffer = malloc(cineon->lineBufferLength * 4); if (cineon->lineBuffer == 0) { if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", cineon->lineBufferLength * 4); cineonClose(cineon); return 0; } cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short)); if (cineon->pixelBuffer == 0) { if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n", (cineon->width * cineon->depth) * (int)sizeof(unsigned short)); cineonClose(cineon); return 0; } cineon->pixelBufferUsed = 0; if (logimage_fseek(cineon, cineon->imageOffset, SEEK_SET) != 0) { if (verbose) d_printf("Couldn't seek to image data at %d\n", cineon->imageOffset); cineonClose(cineon); return 0; } cineon->fileYPos = 0; logImageGetByteConversionDefaults(&cineon->params); setupLut(cineon); cineon->getRow = &cineonGetRowBytes; cineon->setRow = 0; cineon->close = &cineonClose; if (verbose) { verboseMe(cineon); } return cineon; }
LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize) { DpxMainHeader header; LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__); const char *filename = (const char *)byteStuff; int i; if (dpx == NULL) { if (verbose) printf("DPX: Failed to malloc dpx file structure.\n"); return NULL; } /* zero the header */ memset(&header, 0, sizeof(DpxMainHeader)); /* for close routine */ dpx->file = NULL; if (fromMemory == 0) { /* byteStuff is then the filename */ dpx->file = BLI_fopen(filename, "rb"); if (dpx->file == NULL) { if (verbose) printf("DPX: Failed to open file \"%s\".\n", filename); logImageClose(dpx); return NULL; } /* not used in this case */ dpx->memBuffer = NULL; dpx->memCursor = NULL; dpx->memBufferSize = 0; } else { dpx->memBuffer = (unsigned char *)byteStuff; dpx->memCursor = (unsigned char *)byteStuff; dpx->memBufferSize = bufferSize; } if (logimage_fread(&header, sizeof(header), 1, dpx) == 0) { if (verbose) printf("DPX: Not enough data for header in \"%s\".\n", byteStuff); logImageClose(dpx); return NULL; } /* endianness determination */ if (header.fileHeader.magic_num == swap_uint(DPX_FILE_MAGIC, 1)) { dpx->isMSB = 1; if (verbose) printf("DPX: File is MSB.\n"); } else if (header.fileHeader.magic_num == DPX_FILE_MAGIC) { dpx->isMSB = 0; if (verbose) printf("DPX: File is LSB.\n"); } else { if (verbose) { printf("DPX: Bad magic number %u in \"%s\".\n", header.fileHeader.magic_num, byteStuff); } logImageClose(dpx); return NULL; } dpx->srcFormat = format_DPX; dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB); if (dpx->numElements == 0) { if (verbose) printf("DPX: Wrong number of elements: %d\n", dpx->numElements); logImageClose(dpx); return NULL; } dpx->width = swap_uint(header.imageHeader.pixels_per_line, dpx->isMSB); dpx->height = swap_uint(header.imageHeader.lines_per_element, dpx->isMSB); if (dpx->width == 0 || dpx->height == 0) { if (verbose) printf("DPX: Wrong image dimension: %dx%d\n", dpx->width, dpx->height); logImageClose(dpx); return NULL; } dpx->depth = 0; for (i = 0; i < dpx->numElements; i++) { dpx->element[i].descriptor = header.imageHeader.element[i].descriptor; switch (dpx->element[i].descriptor) { case descriptor_Red: case descriptor_Green: case descriptor_Blue: case descriptor_Alpha: case descriptor_Luminance: case descriptor_Chrominance: dpx->depth++; dpx->element[i].depth = 1; break; case descriptor_CbYCrY: dpx->depth += 2; dpx->element[i].depth = 2; break; case descriptor_RGB: case descriptor_CbYCr: case descriptor_CbYACrYA: dpx->depth += 3; dpx->element[i].depth = 3; break; case descriptor_RGBA: case descriptor_ABGR: case descriptor_CbYCrA: dpx->depth += 4; dpx->element[i].depth = 4; break; case descriptor_Depth: case descriptor_Composite: /* unsupported */ break; } if (dpx->depth == 0 || dpx->depth > 4) { if (verbose) printf("DPX: Unsupported image depth: %d\n", dpx->depth); logImageClose(dpx); return NULL; } dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample; if (dpx->element[i].bitsPerSample != 1 && dpx->element[i].bitsPerSample != 8 && dpx->element[i].bitsPerSample != 10 && dpx->element[i].bitsPerSample != 12 && dpx->element[i].bitsPerSample != 16) { if (verbose) printf("DPX: Unsupported bitsPerSample for elements %d: %d\n", i, dpx->element[i].bitsPerSample); logImageClose(dpx); return NULL; } dpx->element[i].maxValue = powf(2, dpx->element[i].bitsPerSample) - 1.0f; dpx->element[i].packing = swap_ushort(header.imageHeader.element[i].packing, dpx->isMSB); if (dpx->element[i].packing > 2) { if (verbose) printf("DPX: Unsupported packing for element %d: %d\n", i, dpx->element[i].packing); logImageClose(dpx); return NULL; } /* Sometimes, the offset is not set correctly in the header */ dpx->element[i].dataOffset = swap_uint(header.imageHeader.element[i].data_offset, dpx->isMSB); if (dpx->element[i].dataOffset == 0 && dpx->numElements == 1) dpx->element[i].dataOffset = swap_uint(header.fileHeader.offset, dpx->isMSB); if (dpx->element[i].dataOffset == 0) { if (verbose) printf("DPX: Image header is corrupted.\n"); logImageClose(dpx); return NULL; } dpx->element[i].transfer = header.imageHeader.element[i].transfer; /* if undefined, assign default */ dpx->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, dpx->isMSB); dpx->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity, dpx->isMSB); dpx->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data, dpx->isMSB); dpx->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity, dpx->isMSB); switch (dpx->element[i].descriptor) { case descriptor_Red: case descriptor_Green: case descriptor_Blue: case descriptor_Alpha: case descriptor_RGB: case descriptor_RGBA: case descriptor_ABGR: if (dpx->element[i].refLowData == DPX_UNDEFINED_U32) dpx->element[i].refLowData = 0; if (dpx->element[i].refHighData == DPX_UNDEFINED_U32) dpx->element[i].refHighData = (unsigned int)dpx->element[i].maxValue; if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity)) dpx->element[i].refLowQuantity = 0.0f; if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refHighQuantity)) { if (dpx->element[i].transfer == transfer_PrintingDensity || dpx->element[i].transfer == transfer_Logarithmic) dpx->element[i].refHighQuantity = 2.048f; else dpx->element[i].refHighQuantity = dpx->element[i].maxValue; } break; case descriptor_Luminance: case descriptor_Chrominance: case descriptor_CbYCrY: case descriptor_CbYCr: case descriptor_CbYACrYA: case descriptor_CbYCrA: if (dpx->element[i].refLowData == DPX_UNDEFINED_U32) dpx->element[i].refLowData = 16.0f / 255.0f * dpx->element[i].maxValue; if (dpx->element[i].refHighData == DPX_UNDEFINED_U32) dpx->element[i].refHighData = 235.0f / 255.0f * dpx->element[i].maxValue; if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity)) dpx->element[i].refLowQuantity = 0.0f; if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refHighQuantity)) dpx->element[i].refHighQuantity = 0.7f; break; default: break; } } dpx->referenceBlack = swap_float(header.televisionHeader.black_level, dpx->isMSB); dpx->referenceWhite = swap_float(header.televisionHeader.white_level, dpx->isMSB); dpx->gamma = swap_float(header.televisionHeader.gamma, dpx->isMSB); if ((dpx->referenceBlack == DPX_UNDEFINED_R32 || isnan(dpx->referenceBlack)) || (dpx->referenceWhite == DPX_UNDEFINED_R32 || dpx->referenceWhite <= dpx->referenceBlack || isnan(dpx->referenceWhite)) || (dpx->gamma == DPX_UNDEFINED_R32 || dpx->gamma <= 0 || isnan(dpx->gamma))) { dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue; dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue; dpx->gamma = 1.7f; } if (verbose) { printf("size %d x %d x %d elements\n", dpx->width, dpx->height, dpx->numElements); for (i = 0; i < dpx->numElements; i++) { printf(" Element %d:\n", i); printf(" Bits per sample: %d\n", dpx->element[i].bitsPerSample); printf(" Depth: %d\n", dpx->element[i].depth); printf(" Transfer characteristics: %d\n", dpx->element[i].transfer); printf(" Packing: %d\n", dpx->element[i].packing); printf(" Descriptor: %d\n", dpx->element[i].descriptor); printf(" Data offset: %d\n", dpx->element[i].dataOffset); printf(" Reference low data: %u\n", dpx->element[i].refLowData); printf(" Reference low quantity: %f\n", dpx->element[i].refLowQuantity); printf(" Reference high data: %u\n", dpx->element[i].refHighData); printf(" Reference high quantity: %f\n", dpx->element[i].refHighQuantity); printf("\n"); } printf("Gamma: %f\n", dpx->gamma); printf("Reference black: %f\n", dpx->referenceBlack); printf("Reference white: %f\n", dpx->referenceWhite); printf("----------------------------\n"); } return dpx; }
CineonFile* cineonCreate(const char* filename, int width, int height, int depth) { /* Note: always write files in network order */ /* By the spec, it shouldn't matter, but ... */ CineonGenericHeader header; const char* shortFilename = 0; CineonFile* cineon = (CineonFile*)malloc(sizeof(CineonFile)); if (cineon == 0) { if (verbose) d_printf("Failed to malloc cineon file structure.\n"); return 0; } memset(&header, 0, sizeof(header)); /* for close routine */ cineon->file = 0; cineon->lineBuffer = 0; cineon->pixelBuffer = 0; cineon->file = BLI_fopen(filename, "wb"); if (cineon->file == 0) { if (verbose) d_printf("Couldn't open file %s\n", filename); cineonClose(cineon); return 0; } cineon->reading = 0; cineon->width = width; cineon->height = height; cineon->depth = depth; cineon->bitsPerPixel = 10; cineon->imageOffset = sizeof(CineonGenericHeader); cineon->lineBufferLength = pixelsToLongs(cineon->width * cineon->depth); cineon->lineBuffer = malloc(cineon->lineBufferLength * 4); if (cineon->lineBuffer == 0) { if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", cineon->lineBufferLength * 4); cineonClose(cineon); return 0; } cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short)); if (cineon->pixelBuffer == 0) { if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n", (cineon->width * cineon->depth) * (int)sizeof(unsigned short)); cineonClose(cineon); return 0; } cineon->pixelBufferUsed = 0; /* find trailing part of filename */ shortFilename = strrchr(filename, '/'); if (shortFilename == 0) { shortFilename = filename; } else { ++shortFilename; } if (initCineonGenericHeader(cineon, &header, shortFilename) != 0) { cineonClose(cineon); return 0; } if (fwrite(&header, sizeof(header), 1, cineon->file) == 0) { if (verbose) d_printf("Couldn't write image header\n"); cineonClose(cineon); return 0; } cineon->fileYPos = 0; logImageGetByteConversionDefaults(&cineon->params); setupLut(cineon); cineon->getRow = 0; cineon->setRow = &cineonSetRowBytes; cineon->close = &cineonClose; return cineon; }
int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) { png_structp png_ptr; png_infop info_ptr; unsigned char *pixels = NULL; unsigned char *from, *to; unsigned short *pixels16 = NULL, *to16; float *from_float, from_straight[4]; png_bytepp row_pointers = NULL; int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY; FILE *fp = NULL; int is_16bit = (ibuf->ftype & PNG_16BIT) && ibuf->rect_float; /* use the jpeg quality setting for compression */ int compression; compression = (int)(((float)(ibuf->ftype & 0xff) / 11.1111f)); compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression); /* for prints */ if (flags & IB_mem) name = "<memory>"; bytesperpixel = (ibuf->planes + 7) >> 3; if ((bytesperpixel > 4) || (bytesperpixel == 2)) { printf("imb_savepng: Cunsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name); return (0); } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", name); return 0; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", name); return 0; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); printf("imb_savepng: Cannot setjmp for file: '%s'\n", name); return 0; } /* copy image data */ if (is_16bit) pixels16 = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned short), "png 16bit pixels"); else pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "png 8bit pixels"); if (pixels == NULL && pixels16 == NULL) { png_destroy_write_struct(&png_ptr, &info_ptr); printf("imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n", ibuf->x, ibuf->y, bytesperpixel, name); return 0; } from = (unsigned char *) ibuf->rect; to = pixels; from_float = ibuf->rect_float; to16 = pixels16; switch (bytesperpixel) { case 4: color_type = PNG_COLOR_TYPE_RGBA; if (is_16bit) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4(from_straight, from_float); to16[0] = FTOUSHORT(from_straight[0]); to16[1] = FTOUSHORT(from_straight[1]); to16[2] = FTOUSHORT(from_straight[2]); to16[3] = FTOUSHORT(from_straight[3]); to16 += 4; from_float += 4; } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to[0] = from[0]; to[1] = from[1]; to[2] = from[2]; to[3] = from[3]; to += 4; from += 4; } } break; case 3: color_type = PNG_COLOR_TYPE_RGB; if (is_16bit) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4(from_straight, from_float); to16[0] = FTOUSHORT(from_straight[0]); to16[1] = FTOUSHORT(from_straight[1]); to16[2] = FTOUSHORT(from_straight[2]); to16 += 3; from_float += 4; } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to[0] = from[0]; to[1] = from[1]; to[2] = from[2]; to += 3; from += 4; } } break; case 1: color_type = PNG_COLOR_TYPE_GRAY; if (is_16bit) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4(from_straight, from_float); to16[0] = FTOUSHORT(from_straight[0]); to16++; from_float += 4; } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to[0] = from[0]; to++; from += 4; } } break; } if (flags & IB_mem) { /* create image in memory */ imb_addencodedbufferImBuf(ibuf); ibuf->encodedsize = 0; png_set_write_fn(png_ptr, (png_voidp) ibuf, WriteData, Flush); } else { fp = BLI_fopen(name, "wb"); if (!fp) { png_destroy_write_struct(&png_ptr, &info_ptr); if (pixels) MEM_freeN(pixels); if (pixels16) MEM_freeN(pixels16); printf("imb_savepng: Cannot open file for writing: '%s'\n", name); return 0; } png_init_io(png_ptr, fp); } #if 0 png_set_filter(png_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH | PNG_ALL_FILTERS); #endif png_set_compression_level(png_ptr, compression); /* png image settings */ png_set_IHDR(png_ptr, info_ptr, ibuf->x, ibuf->y, is_16bit ? 16 : 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* image text info */ if (ibuf->metadata) { png_text *metadata; ImMetaData *iptr; int num_text = 0; iptr = ibuf->metadata; while (iptr) { num_text++; iptr = iptr->next; } metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata"); iptr = ibuf->metadata; num_text = 0; while (iptr) { metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE; metadata[num_text].key = iptr->key; metadata[num_text].text = iptr->value; num_text++; iptr = iptr->next; } png_set_text(png_ptr, info_ptr, metadata, num_text); MEM_freeN(metadata); } if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) { png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER); } /* write the file header information */ png_write_info(png_ptr, info_ptr); #ifdef __LITTLE_ENDIAN__ png_set_swap(png_ptr); #endif /* allocate memory for an array of row-pointers */ row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers"); if (row_pointers == NULL) { printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name); png_destroy_write_struct(&png_ptr, &info_ptr); if (pixels) MEM_freeN(pixels); if (pixels16) MEM_freeN(pixels16); if (fp) { fclose(fp); } return 0; } /* set the individual row-pointers to point at the correct offsets */ if (is_16bit) { for (i = 0; i < ibuf->y; i++) { row_pointers[ibuf->y - 1 - i] = (png_bytep) ((unsigned short *)pixels16 + (i * ibuf->x) * bytesperpixel); } } else { for (i = 0; i < ibuf->y; i++) { row_pointers[ibuf->y - 1 - i] = (png_bytep) ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char)); } } /* write out the entire image data in one call */ png_write_image(png_ptr, row_pointers); /* write the additional chunks to the PNG file (not really needed) */ png_write_end(png_ptr, info_ptr); /* clean up */ if (pixels) MEM_freeN(pixels); if (pixels16) MEM_freeN(pixels16); MEM_freeN(row_pointers); png_destroy_write_struct(&png_ptr, &info_ptr); if (fp) { fflush(fp); fclose(fp); } return(1); }
static void blender_crash_handler(int signum) { #if 0 { char fname[FILE_MAX]; if (!G.main->name[0]) { BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend"); } else { BLI_strncpy(fname, G.main->name, sizeof(fname)); BLI_replace_extension(fname, sizeof(fname), ".crash.blend"); } printf("Writing: %s\n", fname); fflush(stdout); BKE_undo_save_file(fname); } #endif FILE *fp; char header[512]; wmWindowManager *wm = G.main->wm.first; char fname[FILE_MAX]; if (!G.main->name[0]) { BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), "blender.crash.txt"); } else { BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), BLI_path_basename(G.main->name)); BLI_replace_extension(fname, sizeof(fname), ".crash.txt"); } printf("Writing: %s\n", fname); fflush(stdout); BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Revision: %s\n", BLEND_VERSION_ARG, #ifdef BUILD_DATE build_rev #else "Unknown" #endif ); /* open the crash log */ errno = 0; fp = BLI_fopen(fname, "wb"); if (fp == NULL) { fprintf(stderr, "Unable to save '%s': %s\n", fname, errno ? strerror(errno) : "Unknown error opening file"); } else { if (wm) { BKE_report_write_file_fp(fp, &wm->reports, header); } blender_crash_handler_backtrace(fp); fclose(fp); } /* really crash */ signal(signum, SIG_DFL); #ifndef WIN32 kill(getpid(), signum); #else TerminateProcess(GetCurrentProcess(), signum); #endif }
int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags) { char buf[20] = {0}; FILE *fildes; short ok = 0; (void)flags; /* unused */ buf[16] = (ibuf->planes + 0x7) & ~0x7; if (ibuf->planes > 8) { buf[2] = 10; } else { buf[2] = 11; } if (ibuf->ftype == RAWTGA) buf[2] &= ~8; buf[8] = 0; buf[9] = 0; buf[10] = 0; buf[11] = 0; buf[12] = ibuf->x & 0xff; buf[13] = ibuf->x >> 8; buf[14] = ibuf->y & 0xff; buf[15] = ibuf->y >> 8; /* Don't forget to indicate that your 32 bit * targa uses 8 bits for the alpha channel! */ if (ibuf->planes == 32) { buf[17] |= 0x08; } fildes = BLI_fopen(name, "wb"); if (!fildes) return 0; if (fwrite(buf, 1, 18, fildes) != 18) { fclose(fildes); return (0); } if (ibuf->ftype == RAWTGA) { ok = dumptarga(ibuf, fildes); } else { switch ((ibuf->planes + 7) >> 3) { case 1: ok = makebody_tga(ibuf, fildes, tga_out1); break; case 2: ok = makebody_tga(ibuf, fildes, tga_out2); break; case 3: ok = makebody_tga(ibuf, fildes, tga_out3); break; case 4: ok = makebody_tga(ibuf, fildes, tga_out4); break; } } fclose(fildes); return (ok); }
static bool python_script_exec( bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump) { Main *bmain_old = CTX_data_main(C); PyObject *main_mod = NULL; PyObject *py_dict = NULL, *py_result = NULL; PyGILState_STATE gilstate; BLI_assert(fn || text); if (fn == NULL && text == NULL) { return 0; } bpy_context_set(C, &gilstate); PyC_MainModule_Backup(&main_mod); if (text) { char fn_dummy[FILE_MAXDIR]; bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ char *buf; PyObject *fn_dummy_py; fn_dummy_py = PyC_UnicodeFromByte(fn_dummy); buf = txt_to_buf(text); text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1); MEM_freeN(buf); Py_DECREF(fn_dummy_py); if (PyErr_Occurred()) { if (do_jump) { python_script_error_jump_text(text); } BPY_text_free_code(text); } } if (text->compiled) { py_dict = PyC_DefaultNameSpace(fn_dummy); py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); } } else { FILE *fp = BLI_fopen(fn, "r"); if (fp) { py_dict = PyC_DefaultNameSpace(fn); #ifdef _WIN32 /* Previously we used PyRun_File to run directly the code on a FILE * object, but as written in the Python/C API Ref Manual, chapter 2, * 'FILE structs for different C libraries can be different and * incompatible'. * So now we load the script file data to a buffer */ { const char *pystring = "ns = globals().copy()\n" "with open(__file__, 'rb') as f: exec(compile(f.read(), __file__, 'exec'), ns)"; fclose(fp); py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); } #else py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); fclose(fp); #endif } else { PyErr_Format(PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); py_result = NULL; } } if (!py_result) { if (text) { if (do_jump) { /* ensure text is valid before use, the script may have freed its self */ Main *bmain_new = CTX_data_main(C); if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->text, text) != -1)) { python_script_error_jump_text(text); } } } BPy_errors_to_report(reports); } else { Py_DECREF(py_result); } if (py_dict) { #ifdef PYMODULE_CLEAR_WORKAROUND PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); PyObject *dict_back = mmod->md_dict; /* freeing the module will clear the namespace, * gives problems running classes defined in this namespace being used later. */ mmod->md_dict = NULL; Py_DECREF(dict_back); #endif #undef PYMODULE_CLEAR_WORKAROUND } PyC_MainModule_Restore(main_mod); bpy_context_clear(C, &gilstate); return (py_result != NULL); }
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump) { PyObject *main_mod = NULL; PyObject *py_dict = NULL, *py_result = NULL; PyGILState_STATE gilstate; BLI_assert(fn || text); if (fn == NULL && text == NULL) { return 0; } bpy_context_set(C, &gilstate); PyC_MainModule_Backup(&main_mod); if (text) { char fn_dummy[FILE_MAXDIR]; bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ char *buf = txt_to_buf(text); text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input); MEM_freeN(buf); if (PyErr_Occurred()) { if (do_jump) { python_script_error_jump_text(text); } BPY_text_free_code(text); } } if (text->compiled) { py_dict = PyC_DefaultNameSpace(fn_dummy); py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); } } else { FILE *fp = BLI_fopen(fn, "r"); if (fp) { py_dict = PyC_DefaultNameSpace(fn); #ifdef _WIN32 /* Previously we used PyRun_File to run directly the code on a FILE * object, but as written in the Python/C API Ref Manual, chapter 2, * 'FILE structs for different C libraries can be different and * incompatible'. * So now we load the script file data to a buffer */ { char *pystring; fclose(fp); pystring = MEM_mallocN(strlen(fn) + 32, "pystring"); pystring[0] = '\0'; sprintf(pystring, "exec(open(r'%s').read())", fn); py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); MEM_freeN(pystring); } #else py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); fclose(fp); #endif } else { PyErr_Format(PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); py_result = NULL; } } if (!py_result) { if (text) { if (do_jump) { python_script_error_jump_text(text); } } BPy_errors_to_report(reports); } else { Py_DECREF(py_result); } if (py_dict) { #ifdef PYMODULE_CLEAR_WORKAROUND PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); PyObject *dict_back = mmod->md_dict; /* freeing the module will clear the namespace, * gives problems running classes defined in this namespace being used later. */ mmod->md_dict = NULL; Py_DECREF(dict_back); #endif #undef PYMODULE_CLEAR_WORKAROUND } PyC_MainModule_Restore(main_mod); bpy_context_clear(C, &gilstate); return (py_result != NULL); }
LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize) { CineonMainHeader header; LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__); const char *filename = (const char *)byteStuff; int i; unsigned int dataOffset; if (cineon == NULL) { if (verbose) printf("Cineon: Failed to malloc cineon file structure.\n"); return NULL; } /* zero the header */ memset(&header, 0, sizeof(CineonMainHeader)); /* for close routine */ cineon->file = NULL; if (fromMemory == 0) { /* byteStuff is then the filename */ cineon->file = BLI_fopen(filename, "rb"); if (cineon->file == NULL) { if (verbose) printf("Cineon: Failed to open file \"%s\".\n", filename); logImageClose(cineon); return NULL; } /* not used in this case */ cineon->memBuffer = NULL; cineon->memCursor = NULL; cineon->memBufferSize = 0; } else { cineon->memBuffer = (unsigned char *)byteStuff; cineon->memCursor = (unsigned char *)byteStuff; cineon->memBufferSize = bufferSize; } if (logimage_fread(&header, sizeof(header), 1, cineon) == 0) { if (verbose) printf("Cineon: Not enough data for header in \"%s\".\n", byteStuff); logImageClose(cineon); return NULL; } /* endianness determination */ if (header.fileHeader.magic_num == swap_uint(CINEON_FILE_MAGIC, 1)) { cineon->isMSB = 1; if (verbose) printf("Cineon: File is MSB.\n"); } else if (header.fileHeader.magic_num == CINEON_FILE_MAGIC) { cineon->isMSB = 0; if (verbose) printf("Cineon: File is LSB.\n"); } else { if (verbose) printf("Cineon: Bad magic number %lu in \"%s\".\n", (unsigned long)header.fileHeader.magic_num, byteStuff); logImageClose(cineon); return NULL; } cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB); cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB); if (cineon->width == 0 || cineon->height == 0) { if (verbose) printf("Cineon: Wrong image dimension: %dx%d\n", cineon->width, cineon->height); logImageClose(cineon); return NULL; } cineon->depth = header.imageHeader.elements_per_image; cineon->srcFormat = format_Cineon; if (header.imageHeader.interleave == 0) cineon->numElements = 1; else if (header.imageHeader.interleave == 2) cineon->numElements = header.imageHeader.elements_per_image; else { if (verbose) printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave); logImageClose(cineon); return NULL; } if (cineon->depth == 1) { /* Grayscale image */ cineon->element[0].descriptor = descriptor_Luminance; cineon->element[0].transfer = transfer_Linear; cineon->element[0].depth = 1; } else if (cineon->depth == 3) { /* RGB image */ if (cineon->numElements == 1) { cineon->element[0].descriptor = descriptor_RGB; cineon->element[0].transfer = transfer_PrintingDensity; cineon->element[0].depth = 3; } else if (cineon->numElements == 3) { cineon->element[0].descriptor = descriptor_Red; cineon->element[0].transfer = transfer_PrintingDensity; cineon->element[0].depth = 1; cineon->element[1].descriptor = descriptor_Green; cineon->element[1].transfer = transfer_PrintingDensity; cineon->element[1].depth = 1; cineon->element[2].descriptor = descriptor_Blue; cineon->element[2].transfer = transfer_PrintingDensity; cineon->element[2].depth = 1; } } else { if (verbose) printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth); logImageClose(cineon); return NULL; } dataOffset = swap_uint(header.fileHeader.offset, cineon->isMSB); for (i = 0; i < cineon->numElements; i++) { cineon->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample; cineon->element[i].maxValue = powf(2, cineon->element[i].bitsPerSample) - 1.0f; cineon->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, cineon->isMSB); cineon->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity, cineon->isMSB); cineon->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data, cineon->isMSB); cineon->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity, cineon->isMSB); switch (header.imageHeader.packing) { case 0: cineon->element[i].packing = 0; break; case 5: cineon->element[i].packing = 1; break; case 6: cineon->element[i].packing = 2; break; default: /* Not supported */ if (verbose) printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing); logImageClose(cineon); return NULL; } if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32) cineon->element[i].refLowData = 0; if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32) cineon->element[i].refHighData = (unsigned int)cineon->element[i].maxValue; if (cineon->element[i].refLowQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refLowQuantity)) cineon->element[i].refLowQuantity = 0.0f; if (cineon->element[i].refHighQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refHighQuantity)) { if (cineon->element[i].transfer == transfer_PrintingDensity) cineon->element[i].refHighQuantity = 2.048f; else cineon->element[i].refHighQuantity = cineon->element[i].maxValue; } cineon->element[i].dataOffset = dataOffset; dataOffset += cineon->height * getRowLength(cineon->width, cineon->element[i]); } cineon->referenceBlack = 95.0f / 1023.0f * cineon->element[0].maxValue; cineon->referenceWhite = 685.0f / 1023.0f * cineon->element[0].maxValue; cineon->gamma = 1.7f; if (verbose) { printf("size %d x %d x %d elements\n", cineon->width, cineon->height, cineon->numElements); for (i = 0; i < cineon->numElements; i++) { printf(" Element %d:\n", i); printf(" Bits per sample: %d\n", cineon->element[i].bitsPerSample); printf(" Depth: %d\n", cineon->element[i].depth); printf(" Transfer characteristics: %d\n", cineon->element[i].transfer); printf(" Packing: %d\n", cineon->element[i].packing); printf(" Descriptor: %d\n", cineon->element[i].descriptor); printf(" Data offset: %u\n", cineon->element[i].dataOffset); printf(" Reference low data: %u\n", cineon->element[i].refLowData); printf(" Reference low quantity: %f\n", cineon->element[i].refLowQuantity); printf(" Reference high data: %u\n", cineon->element[i].refHighData); printf(" Reference high quantity: %f\n", cineon->element[i].refHighQuantity); printf("\n"); } printf("Gamma: %f\n", cineon->gamma); printf("Reference black: %f\n", cineon->referenceBlack); printf("Reference white: %f\n", cineon->referenceWhite); printf("----------------------------\n"); } return cineon; }
LogImageFile *cineonCreate(const char *filename, int width, int height, int bitsPerSample, const char *creator) { CineonMainHeader header; const char *shortFilename = NULL; /* unsigned char pad[6044]; */ LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__); if (cineon == NULL) { if (verbose) printf("cineon: Failed to malloc cineon file structure.\n"); return NULL; } /* Only 10 bits Cineon are supported */ if (bitsPerSample != 10) { if (verbose) printf("cineon: Only 10 bits Cineon are supported.\n"); logImageClose(cineon); return NULL; } cineon->width = width; cineon->height = height; cineon->element[0].bitsPerSample = 10; cineon->element[0].dataOffset = sizeof(CineonMainHeader); cineon->element[0].maxValue = 1023; cineon->isMSB = 1; cineon->numElements = 1; cineon->element[0].packing = 1; cineon->depth = 3; cineon->element[0].depth = 3; cineon->element[0].descriptor = descriptor_RGB; cineon->element[0].transfer = transfer_PrintingDensity; cineon->element[0].refHighQuantity = 2.048f; cineon->element[0].refLowQuantity = 0; cineon->element[0].refLowData = 0; cineon->element[0].refHighData = cineon->element[0].maxValue; cineon->referenceWhite = 685.0f; cineon->referenceBlack = 95.0f; cineon->gamma = 1.7f; shortFilename = strrchr(filename, '/'); if (shortFilename == NULL) shortFilename = filename; else shortFilename++; cineon->file = BLI_fopen(filename, "wb"); if (cineon->file == NULL) { if (verbose) printf("cineon: Couldn't open file %s\n", filename); logImageClose(cineon); return NULL; } fillCineonMainHeader(cineon, &header, shortFilename, creator); if (fwrite(&header, sizeof(header), 1, cineon->file) == 0) { if (verbose) printf("cineon: Couldn't write image header\n"); logImageClose(cineon); return NULL; } return cineon; }
int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) { png_structp png_ptr; png_infop info_ptr; unsigned char *pixels = NULL; unsigned char *from, *to; unsigned short *pixels16 = NULL, *to16; float *from_float, from_straight[4]; png_bytepp row_pointers = NULL; int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY; FILE *fp = NULL; bool is_16bit = (ibuf->foptions.flag & PNG_16BIT) != 0; bool has_float = (ibuf->rect_float != NULL); int channels_in_float = ibuf->channels ? ibuf->channels : 4; float (*chanel_colormanage_cb)(float); size_t num_bytes; /* use the jpeg quality setting for compression */ int compression; compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f)); compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression); if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { /* float buffer was managed already, no need in color space conversion */ chanel_colormanage_cb = channel_colormanage_noop; } else { /* standard linear-to-srgb conversion if float buffer wasn't managed */ chanel_colormanage_cb = linearrgb_to_srgb; } /* for prints */ if (flags & IB_mem) name = "<memory>"; bytesperpixel = (ibuf->planes + 7) >> 3; if ((bytesperpixel > 4) || (bytesperpixel == 2)) { printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name); return (0); } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", name); return 0; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", name); return 0; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); printf("imb_savepng: Cannot setjmp for file: '%s'\n", name); return 0; } /* copy image data */ num_bytes = ((size_t)ibuf->x) * ibuf->y * bytesperpixel; if (is_16bit) pixels16 = MEM_mallocN(num_bytes * sizeof(unsigned short), "png 16bit pixels"); else pixels = MEM_mallocN(num_bytes * sizeof(unsigned char), "png 8bit pixels"); if (pixels == NULL && pixels16 == NULL) { png_destroy_write_struct(&png_ptr, &info_ptr); printf("imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n", ibuf->x, ibuf->y, bytesperpixel, name); return 0; } from = (unsigned char *) ibuf->rect; to = pixels; from_float = ibuf->rect_float; to16 = pixels16; switch (bytesperpixel) { case 4: color_type = PNG_COLOR_TYPE_RGBA; if (is_16bit) { if (has_float) { if (channels_in_float == 4) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4_v4(from_straight, from_float); to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0])); to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1])); to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2])); to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3])); to16 += 4; from_float += 4; } } else if (channels_in_float == 3) { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); to16[1] = ftoshort(chanel_colormanage_cb(from_float[1])); to16[2] = ftoshort(chanel_colormanage_cb(from_float[2])); to16[3] = 65535; to16 += 4; from_float += 3; } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); to16[2] = to16[1] = to16[0]; to16[3] = 65535; to16 += 4; from_float++; } } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = UPSAMPLE_8_TO_16(from[0]); to16[1] = UPSAMPLE_8_TO_16(from[1]); to16[2] = UPSAMPLE_8_TO_16(from[2]); to16[3] = UPSAMPLE_8_TO_16(from[3]); to16 += 4; from += 4; } } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to[0] = from[0]; to[1] = from[1]; to[2] = from[2]; to[3] = from[3]; to += 4; from += 4; } } break; case 3: color_type = PNG_COLOR_TYPE_RGB; if (is_16bit) { if (has_float) { if (channels_in_float == 4) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4_v4(from_straight, from_float); to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0])); to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1])); to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2])); to16 += 3; from_float += 4; } } else if (channels_in_float == 3) { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); to16[1] = ftoshort(chanel_colormanage_cb(from_float[1])); to16[2] = ftoshort(chanel_colormanage_cb(from_float[2])); to16 += 3; from_float += 3; } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); to16[2] = to16[1] = to16[0]; to16 += 3; from_float++; } } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = UPSAMPLE_8_TO_16(from[0]); to16[1] = UPSAMPLE_8_TO_16(from[1]); to16[2] = UPSAMPLE_8_TO_16(from[2]); to16 += 3; from += 4; } } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to[0] = from[0]; to[1] = from[1]; to[2] = from[2]; to += 3; from += 4; } } break; case 1: color_type = PNG_COLOR_TYPE_GRAY; if (is_16bit) { if (has_float) { float rgb[3]; if (channels_in_float == 4) { for (i = ibuf->x * ibuf->y; i > 0; i--) { premul_to_straight_v4_v4(from_straight, from_float); rgb[0] = chanel_colormanage_cb(from_straight[0]); rgb[1] = chanel_colormanage_cb(from_straight[1]); rgb[2] = chanel_colormanage_cb(from_straight[2]); to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb)); to16++; from_float += 4; } } else if (channels_in_float == 3) { for (i = ibuf->x * ibuf->y; i > 0; i--) { rgb[0] = chanel_colormanage_cb(from_float[0]); rgb[1] = chanel_colormanage_cb(from_float[1]); rgb[2] = chanel_colormanage_cb(from_float[2]); to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb)); to16++; from_float += 3; } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); to16++; from_float++; } } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to16[0] = UPSAMPLE_8_TO_16(from[0]); to16++; from += 4; } } } else { for (i = ibuf->x * ibuf->y; i > 0; i--) { to[0] = from[0]; to++; from += 4; } } break; } if (flags & IB_mem) { /* create image in memory */ imb_addencodedbufferImBuf(ibuf); ibuf->encodedsize = 0; png_set_write_fn(png_ptr, (png_voidp) ibuf, WriteData, Flush); } else { fp = BLI_fopen(name, "wb"); if (!fp) { png_destroy_write_struct(&png_ptr, &info_ptr); if (pixels) MEM_freeN(pixels); if (pixels16) MEM_freeN(pixels16); printf("imb_savepng: Cannot open file for writing: '%s'\n", name); return 0; } png_init_io(png_ptr, fp); } #if 0 png_set_filter(png_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH | PNG_ALL_FILTERS); #endif png_set_compression_level(png_ptr, compression); /* png image settings */ png_set_IHDR(png_ptr, info_ptr, ibuf->x, ibuf->y, is_16bit ? 16 : 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* image text info */ if (ibuf->metadata) { png_text *metadata; IDProperty *prop; int num_text = 0; for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) { if (prop->type == IDP_STRING) { num_text++; } } metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata"); num_text = 0; for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) { if (prop->type == IDP_STRING) { metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE; metadata[num_text].key = prop->name; metadata[num_text].text = IDP_String(prop); num_text++; } } png_set_text(png_ptr, info_ptr, metadata, num_text); MEM_freeN(metadata); } if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) { png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER); } /* write the file header information */ png_write_info(png_ptr, info_ptr); #ifdef __LITTLE_ENDIAN__ png_set_swap(png_ptr); #endif /* allocate memory for an array of row-pointers */ row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers"); if (row_pointers == NULL) { printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name); png_destroy_write_struct(&png_ptr, &info_ptr); if (pixels) MEM_freeN(pixels); if (pixels16) MEM_freeN(pixels16); if (fp) { fclose(fp); } return 0; } /* set the individual row-pointers to point at the correct offsets */ if (is_16bit) { for (i = 0; i < ibuf->y; i++) { row_pointers[ibuf->y - 1 - i] = (png_bytep) ((unsigned short *)pixels16 + (((size_t)i) * ibuf->x) * bytesperpixel); } } else { for (i = 0; i < ibuf->y; i++) { row_pointers[ibuf->y - 1 - i] = (png_bytep) ((unsigned char *)pixels + (((size_t)i) * ibuf->x) * bytesperpixel * sizeof(unsigned char)); } } /* write out the entire image data in one call */ png_write_image(png_ptr, row_pointers); /* write the additional chunks to the PNG file (not really needed) */ png_write_end(png_ptr, info_ptr); /* clean up */ if (pixels) MEM_freeN(pixels); if (pixels16) MEM_freeN(pixels16); MEM_freeN(row_pointers); png_destroy_write_struct(&png_ptr, &info_ptr); if (fp) { fflush(fp); fclose(fp); } return(1); }