1 /* 2 * Copyright 2013, Gerasim Troeglazov, 3dEyes@gmail.com. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <stdlib.h> 8 #include <stdio.h> 9 #include <string.h> 10 11 #include "ConfigView.h" 12 #include "PSDTranslator.h" 13 #include "PSDLoader.h" 14 #include "PSDWriter.h" 15 16 const char *kDocumentCount = "/documentCount"; 17 const char *kDocumentIndex = "/documentIndex"; 18 19 #define kPSDMimeType "image/vnd.adobe.photoshop" 20 #define kPSDName "Photoshop image" 21 22 static const translation_format sInputFormats[] = { 23 { 24 B_TRANSLATOR_BITMAP, 25 B_TRANSLATOR_BITMAP, 26 BITS_IN_QUALITY, 27 BITS_IN_CAPABILITY, 28 "image/x-be-bitmap", 29 "Be Bitmap Format (PSDTranslator)" 30 }, 31 { 32 PSD_IMAGE_FORMAT, 33 B_TRANSLATOR_BITMAP, 34 PSD_IN_QUALITY, 35 PSD_IN_CAPABILITY, 36 kPSDMimeType, 37 kPSDName 38 } 39 }; 40 41 static const translation_format sOutputFormats[] = { 42 { 43 B_TRANSLATOR_BITMAP, 44 B_TRANSLATOR_BITMAP, 45 BITS_OUT_QUALITY, 46 BITS_OUT_CAPABILITY, 47 "image/x-be-bitmap", 48 "Be Bitmap Format (PSDTranslator)" 49 }, 50 { 51 PSD_IMAGE_FORMAT, 52 B_TRANSLATOR_BITMAP, 53 PSD_OUT_QUALITY, 54 PSD_OUT_CAPABILITY, 55 kPSDMimeType, 56 kPSDName 57 } 58 }; 59 60 61 static const TranSetting sDefaultSettings[] = { 62 {B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false}, 63 {B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false} 64 }; 65 66 const uint32 kNumInputFormats = sizeof(sInputFormats) 67 / sizeof(translation_format); 68 const uint32 kNumOutputFormats = sizeof(sOutputFormats) 69 / sizeof(translation_format); 70 const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) 71 / sizeof(TranSetting); 72 73 74 PSDTranslator::PSDTranslator() 75 : BaseTranslator(kPSDName, 76 "Photoshop image translator", 77 PSD_TRANSLATOR_VERSION, 78 sInputFormats, kNumInputFormats, 79 sOutputFormats, kNumOutputFormats, 80 "PSDTranslator", 81 sDefaultSettings, kNumDefaultSettings, 82 B_TRANSLATOR_BITMAP, PSD_IMAGE_FORMAT) 83 { 84 } 85 86 87 PSDTranslator::~PSDTranslator() 88 { 89 } 90 91 92 status_t 93 PSDTranslator::DerivedIdentify(BPositionIO *stream, 94 const translation_format *format, BMessage *ioExtension, 95 translator_info *info, uint32 outType) 96 { 97 if (!outType) 98 outType = B_TRANSLATOR_BITMAP; 99 if (outType != B_TRANSLATOR_BITMAP && outType != PSD_IMAGE_FORMAT) 100 return B_NO_TRANSLATOR; 101 102 PSDLoader psdFile(stream); 103 if (!psdFile.IsSupported()) 104 return B_ILLEGAL_DATA; 105 106 info->type = PSD_IMAGE_FORMAT; 107 info->group = B_TRANSLATOR_BITMAP; 108 info->quality = PSD_IN_QUALITY; 109 info->capability = PSD_IN_CAPABILITY; 110 BString name(kPSDName); 111 name << " (" << psdFile.ColorFormatName() << ")"; 112 strcpy(info->name, name.String()); 113 strcpy(info->MIME, kPSDMimeType); 114 115 return B_OK; 116 } 117 118 119 status_t 120 PSDTranslator::DerivedTranslate(BPositionIO *source, 121 const translator_info *info, BMessage *ioExtension, 122 uint32 outType, BPositionIO *target, int32 baseType) 123 { 124 if (outType != B_TRANSLATOR_BITMAP 125 && outType != PSD_IMAGE_FORMAT) { 126 return B_NO_TRANSLATOR; 127 } 128 129 switch (baseType) { 130 case 0: 131 { 132 if (outType != B_TRANSLATOR_BITMAP) 133 return B_NO_TRANSLATOR; 134 135 PSDLoader psdFile(source); 136 if (!psdFile.IsLoaded()) 137 return B_NO_TRANSLATOR; 138 139 return psdFile.Decode(target); 140 } 141 case 1: 142 { 143 if (outType == PSD_IMAGE_FORMAT) 144 return _TranslateFromBits(source, ioExtension, outType, target); 145 return B_NO_TRANSLATOR; 146 } 147 default: 148 return B_NO_TRANSLATOR; 149 } 150 } 151 152 153 status_t 154 PSDTranslator::_TranslateFromBits(BPositionIO* stream, 155 BMessage* ioExtension, uint32 outType, 156 BPositionIO* target) 157 { 158 TranslatorBitmap bitsHeader; 159 status_t result; 160 result = identify_bits_header(stream, NULL, &bitsHeader); 161 if (result != B_OK) 162 return result; 163 164 if (bitsHeader.colors != B_RGB32 165 && bitsHeader.colors != B_RGBA32) { 166 return B_NO_TRANSLATOR; 167 } 168 169 uint32 width = bitsHeader.bounds.IntegerWidth() + 1; 170 uint32 height = bitsHeader.bounds.IntegerHeight() + 1; 171 172 int32 layerSize = height * width; 173 int32 layersCount = bitsHeader.colors == B_RGB32 ? 3 : 4; 174 175 uint8 *buff = new uint8[layerSize * layersCount]; 176 177 uint8 *ptr = buff; 178 for (int i = 0; i < layerSize; i++) { 179 uint8 rgba[4]; 180 stream->Read(rgba, sizeof(uint32)); 181 ptr[i] = rgba[2]; 182 ptr[i+layerSize] = rgba[1]; 183 ptr[i+layerSize+layerSize] = rgba[0]; 184 if (layersCount == 4) 185 ptr[i+layerSize+layerSize+layerSize] = rgba[3]; 186 } 187 188 PSDWriter psdFile(stream); 189 psdFile.EncodeFromRGBA(target, buff, layersCount, width, height); 190 191 delete buff; 192 193 return B_OK; 194 } 195 196 197 status_t 198 PSDTranslator::DerivedCanHandleImageSize(float width, float height) const 199 { 200 return B_OK; 201 } 202 203 204 BView * 205 PSDTranslator::NewConfigView(TranslatorSettings *settings) 206 { 207 return new ConfigView(settings); 208 } 209 210 211 BTranslator * 212 make_nth_translator(int32 n, image_id you, uint32 flags, ...) 213 { 214 if (n != 0) 215 return NULL; 216 217 return new PSDTranslator(); 218 } 219 220