// The file header contains the basic properties of the image // input: context, the context of psd file // output: status of done psd_status psd_get_file_header(psd_context * context) { psd_file_header_binary header; if(psd_stream_get(context, (psd_uchar *)&header, sizeof(psd_file_header_binary)) == sizeof(psd_file_header_binary)) { // Signature: always equal to '8BPS' if(memcmp(header.signature, "8BPS", 4) != 0) return psd_status_file_signature_error; // Version: always equal to 1 if(PSD_CHAR_TO_SHORT(header.version) != 1) return psd_status_file_version_error; // The height of the image in pixels context->height = PSD_CHAR_TO_INT(header.height_of_image); // Supported range is 1 to 30,000 psd_assert(context->height >= 1 && context->height <= 30000); // The width of the image in pixels context->width = PSD_CHAR_TO_INT(header.width_of_image); // Supported range is 1 to 30,000 psd_assert(context->width >= 1 && context->width <= 30000); // The number of channels in the image, including any alpha channels context->color_channels = context->channels = PSD_CHAR_TO_SHORT(header.number_of_channels); // Supported range is 1 to 56. psd_assert(context->channels >= 1 && context->channels <= 56); // Depth: the number of bits per channel context->depth = PSD_CHAR_TO_SHORT(header.depth); // Supported values are 1, 8, and 16. psd_assert(context->depth == 1 || context->depth == 8 || context->depth == 16); if(context->depth != 1 && context->depth != 8 && context->depth != 16) return psd_status_unsupport_color_depth; // The color mode of the file context->color_mode = (psd_color_mode)PSD_CHAR_TO_SHORT(header.color_mode); switch(context->color_mode) { case psd_color_mode_bitmap: case psd_color_mode_grayscale: case psd_color_mode_indexed: case psd_color_mode_rgb: case psd_color_mode_duotone: break; case psd_color_mode_cmyk: #ifndef PSD_SUPPORT_CMYK return psd_status_unknown_color_mode; #endif break; case psd_color_mode_lab: #ifndef PSD_SUPPORT_LAB return psd_status_unknown_color_mode; #endif break; case psd_color_mode_multichannel: #ifndef PSD_SUPPORT_MULTICHANNEL return psd_status_unknown_color_mode; #endif break; default: psd_assert(0); return psd_status_unknown_color_mode; } } else { return psd_status_fread_error; } return psd_status_done; }
psd_status psd_get_image_resource(psd_context * context) { psd_int length, i, size; psd_ushort ID; psd_uint tag; psd_uchar sizeofname; psd_int sizeofdata, prev_stream_pos; psd_uchar * buffer; //psd_status status; // Length of image resource section length = psd_stream_get_int(context); if(length <= 0) return psd_status_done; // default context->global_angle = 30; context->global_altitude = 30; while(length > 0) { // Signature: '8BIM' tag = psd_stream_get_int(context); if(tag == '8BIM') { length -= 4; // Unique identifier for the resource ID = psd_stream_get_short(context); length -= 2; // Name: Pascal string, padded to make the size even (a null name consists of two bytes of 0) sizeofname = psd_stream_get_char(context); if((sizeofname & 0x01) == 0) sizeofname ++; psd_stream_get_null(context, sizeofname); length -= sizeofname + 1; // Actual size of resource data that follows sizeofdata = psd_stream_get_int(context); length -= 4; // resource data must be even if(sizeofdata & 0x01) sizeofdata ++; length -= sizeofdata; switch(context->load_tag) { case psd_load_tag_thumbnail: if(ID != 1033 && ID != 1036) { psd_stream_get_null(context, sizeofdata); continue; } break; case psd_load_tag_merged: // alpha channels information if(ID != 1006 && ID != 1045 && ID != 1053) { psd_stream_get_null(context, sizeofdata); continue; } break; case psd_load_tag_exif: if(ID != 1058 && ID != 1059) { psd_stream_get_null(context, sizeofdata); continue; } break; } prev_stream_pos = context->stream.current_pos; if(sizeofdata > 0) { switch(ID) { // ResolutionInfo structure case 1005: // Horizontal resolution in pixels per inch. context->resolution_info.hres = psd_stream_get_int(context) / 65536.0f; // 1=display horitzontal resolution in pixels per inch; 2=display horitzontal resolution in pixels per cm. context->resolution_info.hres_unit = psd_stream_get_short(context); // Display width as 1=inches; 2=cm; 3=points; 4=picas; 5=columns. context->resolution_info.width_unit = psd_stream_get_short(context); // Vertial resolution in pixels per inch. context->resolution_info.vres = psd_stream_get_int(context) / 65536.0f; // 1=display vertical resolution in pixels per inch; 2=display vertical resolution in pixels per cm. context->resolution_info.vres_unit = psd_stream_get_short(context); // Display height as 1=inches; 2=cm; 3=points; 4=picas; 5=columns. context->resolution_info.height_unit = psd_stream_get_short(context); context->fill_resolution_info = psd_true; break; // Names of the alpha channels as a series of Pascal strings. case 1006: buffer = (psd_uchar *)psd_malloc(sizeofdata); if(buffer == NULL) return psd_status_malloc_failed; psd_stream_get(context, buffer, sizeofdata); if(context->alpha_channels == 0) { size = 0; // maybe odd while(size + 1 < sizeofdata) { size += *(buffer + size) + 1; context->alpha_channels ++; } context->color_channels = context->channels - context->alpha_channels; context->alpha_channel_info = (psd_alpha_channel_info *)psd_malloc(context->alpha_channels * sizeof(psd_alpha_channel_info)); if(context->alpha_channel_info == NULL) { psd_free(buffer); return psd_status_malloc_failed; } memset(context->alpha_channel_info, 0, context->alpha_channels * sizeof(psd_alpha_channel_info)); } size = 0; for(i = 0; i < context->alpha_channels; i ++) { memcpy(context->alpha_channel_info[i].name, buffer + size + 1, *(buffer + size)); size += *(buffer + size) + 1; } psd_free(buffer); context->fill_alpha_channel_info = psd_true; break; // DisplayInfo structure case 1007: context->display_info.color = psd_stream_get_space_color(context); // 0..100 context->display_info.opacity = psd_stream_get_short(context); psd_assert(context->display_info.opacity >= 0 && context->display_info.opacity <= 100); // selected = 0, protected = 1 context->display_info.kind = psd_stream_get_char(context); // maybe be 2 when color mode is multichannel //psd_assert(context->display_info.kind == 0 || context->display_info.kind == 1); // padding psd_stream_get_char(context); context->fill_display_info = psd_true; break; // The caption as a Pascal string. case 1008: size = psd_stream_get_char(context); psd_stream_get(context, context->caption, size); break; // Layer state information // 2 bytes containing the index of target layer (0 = bottom layer). case 1024: context->target_layer_index = psd_stream_get_short(context); break; // Layers group information // 2 bytes per layer containing a group ID for the dragging groups. Layers in // a group have the same group ID. case 1026: context->layer_group_count = sizeofdata / 2; context->layer_group_id = (psd_ushort *)psd_malloc(context->layer_group_count * 2); if(context->layer_group_id == NULL) return psd_status_malloc_failed; for(i = 0; i < context->layer_group_count; i ++) context->layer_group_id[i] = psd_stream_get_short(context); context->fill_layer_group = psd_true; break; // (Photoshop 4.0) Thumbnail resource for Photoshop 4.0 only case 1033: // (Photoshop 5.0) Thumbnail resource (supersedes resource 1033) case 1036: if(context->load_tag == psd_load_tag_layer) { psd_stream_get_null(context, sizeofdata); continue; } // 1 = kJpegRGB . Also supports kRawRGB (0). context->thumbnail_resource.format = psd_stream_get_int(context); psd_assert(context->thumbnail_resource.format == 0 || context->thumbnail_resource.format == 1); // Width of thumbnail in pixels. context->thumbnail_resource.width = psd_stream_get_int(context); // Height of thumbnail in pixels. context->thumbnail_resource.height = psd_stream_get_int(context); // Padded row bytes = (width * bits per pixel + 31) / 32 * 4. context->thumbnail_resource.width_bytes = psd_stream_get_int(context); // Total size = widthbytes * height * planes context->thumbnail_resource.total_size = psd_stream_get_int(context); // Used for consistency check. context->thumbnail_resource.size_after_compression = psd_stream_get_int(context); context->thumbnail_resource.bits_per_pixel = psd_stream_get_short(context); // Bits per pixel. = 24 psd_assert(context->thumbnail_resource.bits_per_pixel == 24); context->thumbnail_resource.number_of_planes = psd_stream_get_short(context); // Number of planes. = 1 psd_assert(context->thumbnail_resource.number_of_planes == 1); #ifdef PSD_INCLUDE_LIBJPEG if(context->thumbnail_resource.format == 0) { status = psd_thumbnail_decode_raw(&context->thumbnail_resource.thumbnail_data, context->thumbnail_resource.size_after_compression, context); } else { status = psd_thumbnail_decode_jpeg(&context->thumbnail_resource.thumbnail_data, context->thumbnail_resource.size_after_compression, context); } if(status != psd_status_done) return status; #else context->thumbnail_resource.jfif_data = (psd_uchar *)psd_malloc(sizeofdata - 28); if(context->thumbnail_resource.jfif_data == NULL) return psd_status_malloc_failed; psd_stream_get(context, context->thumbnail_resource.jfif_data, sizeofdata - 28); #endif context->fill_thumbnail_resource = psd_true; break; // (Photoshop 4.0) Copyright flag // Boolean indicating whether image is copyrighted. Can be set via // Property suite or by user in File Info... case 1034: context->copyright_flag = (psd_bool)psd_stream_get_short(context); psd_assert(context->copyright_flag == 0 || context->copyright_flag == 1); break; // (Photoshop 5.0) Global Angle // 4 bytes that contain an integer between 0 and 359, which is the global // lighting angle for effects layer. If not present, assumed to be 30. case 1037: context->global_angle = psd_stream_get_int(context); break; // (Photoshop 5.0) Effects visible // 1-byte global flag to show/hide all the effects layer. Only present when // they are hidden. case 1042: context->effects_visible = (psd_bool)psd_stream_get_short(context); psd_assert(context->effects_visible == 0 || context->effects_visible == 1); break; // (Photoshop 5.0) Unicode Alpha Names // Unicode string (4 bytes length followed by string). case 1045: buffer = (psd_uchar *)psd_malloc(sizeofdata); if(buffer == NULL) return psd_status_malloc_failed; psd_stream_get(context, buffer, sizeofdata); if(context->alpha_channels == 0) { size = 0; while(size < sizeofdata) { size += PSD_CHAR_TO_INT(buffer + size) * 2 + 4; context->alpha_channels ++; } context->color_channels = context->channels - context->alpha_channels; context->alpha_channel_info = (psd_alpha_channel_info *)psd_malloc(context->alpha_channels * sizeof(psd_alpha_channel_info)); if(context->alpha_channel_info == NULL) { psd_free(buffer); return psd_status_malloc_failed; } memset(context->alpha_channel_info, 0, context->alpha_channels * sizeof(psd_alpha_channel_info)); } size = 0; for(i = 0; i < context->alpha_channels; i ++) { context->alpha_channel_info[i].unicode_name_length = PSD_CHAR_TO_INT(buffer + size); context->alpha_channel_info[i].unicode_name = (psd_ushort *)psd_malloc(2 * context->alpha_channel_info[i].unicode_name_length); if(context->alpha_channel_info[i].unicode_name == NULL) { psd_free(buffer); return psd_status_malloc_failed; } memcpy(context->alpha_channel_info[i].unicode_name, buffer + size + 4, 2 * context->alpha_channel_info[i].unicode_name_length); size += 2 * context->alpha_channel_info[i].unicode_name_length + 4; } psd_free(buffer); context->fill_alpha_channel_info = psd_true; break; // (Photoshop 6.0) Indexed Color Table Count // 2 bytes for the number of colors in table that are actually defined case 1046: context->indexed_color_table_count = psd_stream_get_short(context); break; // (Photoshop 6.0) Transparency Index. // 2 bytes for the index of transparent color, if any. case 1047: context->transparency_index = psd_stream_get_short(context); break; // (Photoshop 6.0) Global Altitude // 4 byte entry for altitude case 1049: context->global_altitude = psd_stream_get_int(context); break; // (Photoshop 6.0) Alpha Identifiers // 4 bytes of length, followed by 4 bytes each for every alpha identifier. case 1053: if(context->alpha_channels == 0) { context->alpha_channels = sizeofdata / 4; context->color_channels = context->channels - context->alpha_channels; context->alpha_channel_info = (psd_alpha_channel_info *)psd_malloc(context->alpha_channels * sizeof(psd_alpha_channel_info)); if(context->alpha_channel_info == NULL) return psd_status_malloc_failed; memset(context->alpha_channel_info, 0, context->alpha_channels * sizeof(psd_alpha_channel_info)); } for(i = 0; i < context->alpha_channels; i ++) { context->alpha_channel_info[i].identifier = psd_stream_get_int(context); } context->fill_alpha_channel_info = psd_true; break; // (Photoshop 6.0) Version Info // 4 bytes version, 1 byte hasRealMergedData, Unicode string: writer // name, Unicode string: reader name, 4 bytes file version. case 1057: context->version_info.version = psd_stream_get_int(context); context->version_info.has_real_merged_data = psd_stream_get_bool(context); context->version_info.writer_name_length = psd_stream_get_int(context); context->version_info.writer_name = (psd_ushort *)psd_malloc(2 * context->version_info.writer_name_length); if(context->version_info.writer_name == NULL) return psd_status_malloc_failed; psd_stream_get(context, (psd_uchar *)context->version_info.writer_name, 2 * context->version_info.writer_name_length); context->version_info.reader_name_length = psd_stream_get_int(context); context->version_info.reader_name = (psd_ushort *)psd_malloc(2 * context->version_info.reader_name_length); if(context->version_info.reader_name == NULL) return psd_status_malloc_failed; psd_stream_get(context, (psd_uchar *)context->version_info.reader_name, 2 * context->version_info.reader_name_length); context->version_info.file_version = psd_stream_get_int(context); context->fill_version_info = psd_true; break; // if you don't need the following image resource, // you can undef this macro in psd_config.h to reduce the parsing time ///////////////////////////////////////////////////////////////////////////////////////////// #ifdef PSD_GET_ALL_IMAGE_RESOURCE // Border information case 1009: // a fixed number (2 bytes real, 2 bytes fraction) for the border width context->border_info.border_width = psd_fixed_16_16_tofloat((psd_fixed_16_16)psd_stream_get_int(context)); // 2 bytes for border units (1 = inches, 2 = cm, 3 = points, 4 = picas, 5 = columns). context->border_info.border_units = (psd_units)psd_stream_get_short(context); psd_assert(context->border_info.border_units >= psd_units_inches && context->border_info.border_units <= psd_units_columns); context->fill_border_info = psd_true; break; // Print flags // A series of one-byte boolean values (see Page Setup dialog): labels, crop // marks, color bars, registration marks, negative, flip, interpolate, caption, // print flags. case 1011: context->print_flags.labels = psd_stream_get_bool(context); context->print_flags.crop_marks = psd_stream_get_bool(context); context->print_flags.color_bars = psd_stream_get_bool(context); context->print_flags.registration_marks = psd_stream_get_bool(context); context->print_flags.negative = psd_stream_get_bool(context); context->print_flags.flip = psd_stream_get_bool(context); context->print_flags.interpolate = psd_stream_get_bool(context); context->print_flags.caption = psd_stream_get_bool(context); context->print_flags.print_flags = psd_stream_get_bool(context); context->fill_print_flags = psd_true; break; // (Photoshop 4.0) Grid and guides information case 1032: // Version ( = 1) psd_assert(psd_stream_get_int(context) == 1); // Future implementation of document-specific grids (4 bytes horizontal, 4 bytes vertical). context->grid_guides.horz_grid = psd_stream_get_int(context); context->grid_guides.vert_grid = psd_stream_get_int(context); // Number of guide resource blocks (can be 0). context->grid_guides.guide_count = psd_stream_get_int(context); if(context->grid_guides.guide_count > 0) { //Location of guide in document coordinates. Since the guide is either vertical or horizontal, this only has to be one component of the coordinate. context->grid_guides.guide_coordinate = (psd_int *)psd_malloc(context->grid_guides.guide_count * 4); // Direction of guide. VHSelect is a system type of psd_uchar where 0 = vertical, 1 = horizontal. context->grid_guides.guide_direction = (psd_uchar *)psd_malloc(context->grid_guides.guide_count); if(context->grid_guides.guide_coordinate == NULL || context->grid_guides.guide_direction == NULL) { psd_free(context->grid_guides.guide_coordinate); context->grid_guides.guide_coordinate = NULL; psd_free(context->grid_guides.guide_direction); context->grid_guides.guide_direction = NULL; return psd_status_malloc_failed; } for(i = 0; i < context->grid_guides.guide_count; i ++) { context->grid_guides.guide_coordinate[i] = psd_stream_get_int(context); context->grid_guides.guide_direction[i] = psd_stream_get_char(context); } } context->fill_grid_and_guides_info = psd_true; break; // (Photoshop 5.0) Color samplers resource case 1038: // Version ( = 1) psd_assert(psd_stream_get_int(context) == 1); // Number of color samplers to follow. context->color_samplers.number_of_color_samplers = psd_stream_get_int(context); if (context->color_samplers.number_of_color_samplers > 0) { context->color_samplers.resource = (psd_color_samplers_resource *) psd_malloc(sizeof(psd_color_samplers_resource) * context->color_samplers.number_of_color_samplers); if (context->color_samplers.resource == NULL) return psd_status_malloc_failed; for (i = 0; i < context->color_samplers.number_of_color_samplers; i ++) { // The vertical and horizontal position of the point (4 bytes each). context->color_samplers.resource[i].vertical_position = psd_stream_get_int(context); context->color_samplers.resource[i].horizontal_position = psd_stream_get_int(context); // Color Space context->color_samplers.resource[i].color_space = psd_stream_get_short(context); } } context->fill_color_samplers = psd_true; break; // (Photoshop 6.0) Slices case 1050: // Version ( = 6) psd_assert(psd_stream_get_int(context) == 6); // Bounding rectangle for all of the slices: top, left, bottom, right of all the slices context->slices_resource.bounding_top = psd_stream_get_int(context); context->slices_resource.bounding_left = psd_stream_get_int(context); context->slices_resource.bounding_bottom = psd_stream_get_int(context); context->slices_resource.bounding_right = psd_stream_get_int(context); // Name of group of slices: Unicode string size = psd_stream_get_int(context) * 2; psd_stream_get_null(context, size); // Number of slices to follow context->slices_resource.number_of_slices = psd_stream_get_int(context); context->slices_resource.slices_resource_block = (psd_slices_resource_block *)psd_malloc(context->slices_resource.number_of_slices * sizeof(psd_slices_resource_block)); if(context->slices_resource.slices_resource_block == NULL) return psd_status_malloc_failed; memset(context->slices_resource.slices_resource_block, 0, context->slices_resource.number_of_slices * sizeof(psd_slices_resource_block)); for(i = 0; i < context->slices_resource.number_of_slices; i ++) { context->slices_resource.slices_resource_block[i].id = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].group_id = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].origin = psd_stream_get_int(context); // NOTE: Only present if Origin = 1 if(context->slices_resource.slices_resource_block[i].origin == 1) context->slices_resource.slices_resource_block[i].associated_layer_id = psd_stream_get_int(context); // Name: Unicode string size = psd_stream_get_int(context) * 2; psd_stream_get_null(context, size); context->slices_resource.slices_resource_block[i].type = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].left = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].top = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].right = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].bottom = psd_stream_get_int(context); // URL: Unicode string size = psd_stream_get_int(context) * 2; psd_stream_get_null(context, size); // Target: Unicode string size = psd_stream_get_int(context) * 2; psd_stream_get_null(context, size); // Message: Unicode string size = psd_stream_get_int(context) * 2; psd_stream_get_null(context, size); // Alt Tag: Unicode string size = psd_stream_get_int(context) * 2; psd_stream_get_null(context, size); context->slices_resource.slices_resource_block[i].cell_text_is_html = psd_stream_get_char(context); // Cell text: Unicode string size = psd_stream_get_int(context) * 2; psd_stream_get_null(context, size); context->slices_resource.slices_resource_block[i].horizontal_alignment = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].veritcal_alignment = psd_stream_get_int(context); context->slices_resource.slices_resource_block[i].color = psd_argb_to_color(psd_stream_get_char(context), psd_stream_get_char(context), psd_stream_get_char(context), psd_stream_get_char(context)); } context->fill_slices_resource = psd_true; break; // (Photoshop 6.0) URL List case 1054: // 4 byte count of URLs context->url_list.number_of_urls = psd_stream_get_int(context); if (context->url_list.number_of_urls > 0) { context->url_list.items = (psd_url_list_item *)psd_malloc(sizeof(psd_url_list_item) * context->url_list.number_of_urls); if (context->url_list.items == NULL) return psd_status_malloc_failed; memset(context->url_list.items, 0, sizeof(psd_url_list_item) * context->url_list.number_of_urls); } for (i = 0; i < context->url_list.number_of_urls; i ++) { // followed by 4 byte long context->url_list.items[i].tag = psd_stream_get_int(context); // 4 byte ID context->url_list.items[i].ID = psd_stream_get_int(context); // Unicode string for each count. context->url_list.items[i].name_length = psd_stream_get_int(context); context->url_list.items[i].name = (psd_ushort *)psd_malloc(2 * context->url_list.items[i].name_length); if (context->url_list.items[i].name == NULL) return psd_status_malloc_failed; psd_stream_get(context, (psd_uchar *)context->url_list.items[i].name, 2 * context->url_list.items[i].name_length); } context->fill_url_list = psd_true; break; // (Photoshop 7.0) EXIF data 1 case 1058: // (Photoshop 7.0) EXIF data 3 // http://www.pima.net/standards/it10/PIMA15740/exif.htm case 1059: // avoid to get the exif data for twice psd_assert(context->fill_exif_data == psd_false); # ifdef PSD_INCLUDDE_LIBEXIF buffer = (psd_uchar *)psd_malloc(sizeofdata + sizeof(ExifHeader)); if (buffer == NULL) return psd_status_malloc_failed; psd_stream_get(context, buffer + sizeof(ExifHeader), sizeofdata); memcpy(buffer, ExifHeader, sizeof(ExifHeader)); context->exif_data = (psd_uchar *)exif_data_new_from_data(buffer, sizeofdata + sizeof(ExifHeader)); psd_free(buffer); context->fill_exif_data = psd_true; # else // ifdef PSD_INCLUDDE_LIBEXIF context->exif_data = (psd_uchar *)psd_malloc(sizeofdata); if (context->exif_data == NULL) return psd_status_malloc_failed; psd_stream_get(context, context->exif_data, sizeofdata); context->exif_data_length = sizeofdata; context->fill_exif_data = psd_true; # endif // ifdef PSD_INCLUDDE_LIBEXIF break; // (Photoshop 7.0) XMP metadata // File info as XML description // http://Partners.adobe.com/asn/developer/xmp/main.html case 1060: # ifdef PSD_INCLUDE_LIBXML buffer = (psd_uchar *)psd_malloc(sizeofdata); if (buffer == NULL) return psd_status_malloc_failed; psd_stream_get(context, buffer, sizeofdata); context->XMP_metadata = (psd_uchar *)xmlParseMemory(buffer, sizeofdata); psd_free(buffer); context->fill_XMP_metadata = psd_true; # else // ifdef PSD_INCLUDE_LIBXML context->XMP_metadata = (psd_uchar *)psd_malloc(sizeofdata); if (context->XMP_metadata == NULL) return psd_status_malloc_failed; psd_stream_get(context, context->XMP_metadata, sizeofdata); context->XMP_metadata_length = sizeofdata; context->fill_XMP_metadata = psd_true; # endif // ifdef PSD_INCLUDE_LIBXML break; // (Photoshop 7.0) Print scale case 1062: // 2 bytes style (0 = centered, 1 = size to fit, 2 = user defined). context->print_scale.style = psd_stream_get_short(context); psd_assert(context->print_scale.style >= psd_print_centered && context->print_scale.style <= psd_print_user_defined); // 4 bytes x location (floating point). context->print_scale.x_location = psd_stream_get_float(context); // 4 bytes y location (floating point). context->print_scale.y_location = psd_stream_get_float(context); // 4 bytes scale (floating point) context->print_scale.scale = psd_stream_get_float(context); context->fill_print_scale = psd_true; break; // (Photoshop CS) Pixel Aspect Ratio case 1064: // 4 bytes (version = 1) psd_assert(psd_stream_get_int(context) == 1); // 8 bytes double, x / y of a pixel context->pixel_aspect_ratio = psd_stream_get_double(context); break; // Print flags information case 10000: // 2 bytes version ( = 1) psd_assert(psd_stream_get_short(context) == 1); // 1 byte center crop marks context->print_flags_info.center_crop = psd_stream_get_bool(context); // 1 byte ( = 0) psd_assert(psd_stream_get_char(context) == 0); // 4 bytes bleed width value context->print_flags_info.value = psd_stream_get_int(context); // 2 bytes bleed width scale context->print_flags_info.scale = psd_stream_get_short(context); context->fill_print_flags_info = psd_true; break; #endif // ifdef PSD_GET_ALL_IMAGE_RESOURCE ///////////////////////////////////////////////////////////////////////////////////////////// default: #ifdef PSD_GET_PATH_RESOURCE // Photoshop stores its paths as resources of type 8BIM, with IDs in the range 2000 // through 2998. if(ID >= 2000 && ID <= 2998) { psd_get_path(context, sizeofdata); } // If the file contains a resource of type 8BIM with an ID of 2999, then this resource // contains a Pascal¨Cstyle string containing the name of the clipping path to use with this // image when saving it as an EPS file??? else if(ID == 2999) { // we don't find any files includes the name of the clipping path. psd_assert(0); } else #endif // ifdef PSD_GET_PATH_RESOURCE { psd_stream_get_null(context, sizeofdata); } break; } // Filler psd_stream_get_null(context, prev_stream_pos + sizeofdata - context->stream.current_pos); } } else { return psd_status_resource_signature_error; } } return psd_status_done; }