├── .gitignore ├── fig.png ├── README.md └── src ├── PixelSortPiPL.r ├── PixelSort.cpp └── AEPixelSort.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mizt/AEPixelSort/HEAD/fig.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AEPixelSort 2 | 3 | A C implementation of Kim Asendorf's PixelSort for After Effects CC 2015 4 | https://github.com/kimasendorf/ASDFPixelSort (Kim Asendorf 2010) 5 | 6 | https://mizt.github.io/blog/?id=pixelsort 7 | 8 | ![](./fig.png) 9 | -------------------------------------------------------------------------------- /src/PixelSortPiPL.r: -------------------------------------------------------------------------------- 1 | #include "AEConfig.h" 2 | #include "AE_EffectVers.h" 3 | 4 | #ifndef AE_OS_WIN 5 | #include "AE_General.r" 6 | #endif 7 | 8 | resource 'PiPL' (16000) { 9 | { /* array properties: 12 elements */ 10 | /* [1] */ 11 | Kind { 12 | AEEffect 13 | }, 14 | /* [2] */ 15 | Name { 16 | "PixelSort" 17 | }, 18 | /* [3] */ 19 | Category { 20 | "PixelSort" 21 | }, 22 | #ifdef AE_OS_WIN 23 | #ifdef AE_PROC_INTELx64 24 | CodeWin64X86 {"EntryPointFunc"}, 25 | #else 26 | CodeWin32X86 {"EntryPointFunc"}, 27 | #endif 28 | #else 29 | #ifdef AE_OS_MAC 30 | CodeMachOPowerPC {"EntryPointFunc"}, 31 | CodeMacIntel32 {"EntryPointFunc"}, 32 | CodeMacIntel64 {"EntryPointFunc"}, 33 | #endif 34 | #endif 35 | /* [6] */ 36 | AE_PiPL_Version { 37 | 2, 38 | 0 39 | }, 40 | /* [7] */ 41 | AE_Effect_Spec_Version { 42 | PF_PLUG_IN_VERSION, 43 | PF_PLUG_IN_SUBVERS 44 | }, 45 | /* [8] */ 46 | AE_Effect_Version { 47 | 1048577 /* 2.0 */ 48 | }, 49 | /* [9] */ 50 | AE_Effect_Info_Flags { 51 | 0 52 | }, 53 | /* [10] */ 54 | /* [10] */ 55 | AE_Effect_Global_OutFlags { 56 | 0x1000200 57 | 58 | }, 59 | AE_Effect_Global_OutFlags_2 { 60 | 0x00000000 61 | }, 62 | /* [11] */ 63 | AE_Effect_Match_Name { 64 | "PixelSort" 65 | }, 66 | /* [12] */ 67 | AE_Reserved_Info { 68 | 0 69 | } 70 | } 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /src/PixelSort.cpp: -------------------------------------------------------------------------------- 1 | /*******************************************************************/ 2 | /* */ 3 | /* ADOBE CONFIDENTIAL */ 4 | /* _ _ _ _ _ _ _ _ _ _ _ _ _ */ 5 | /* */ 6 | /* Copyright 2007 Adobe Systems Incorporated */ 7 | /* All Rights Reserved. */ 8 | /* */ 9 | /* NOTICE: All information contained herein is, and remains the */ 10 | /* property of Adobe Systems Incorporated and its suppliers, if */ 11 | /* any. The intellectual and technical concepts contained */ 12 | /* herein are proprietary to Adobe Systems Incorporated and its */ 13 | /* suppliers and may be covered by U.S. and Foreign Patents, */ 14 | /* patents in process, and are protected by trade secret or */ 15 | /* copyright law. Dissemination of this information or */ 16 | /* reproduction of this material is strictly forbidden unless */ 17 | /* prior written permission is obtained from Adobe Systems */ 18 | /* Incorporated. */ 19 | /* */ 20 | /*******************************************************************/ 21 | 22 | #include "AEConfig.h" 23 | 24 | #ifdef AE_OS_WIN 25 | #include 26 | #endif 27 | 28 | #include "entry.h" 29 | #include "AE_Effect.h" 30 | #include "A.h" 31 | #include "AE_EffectCB.h" 32 | #include "AE_Macros.h" 33 | #include "Param_Utils.h" 34 | 35 | enum { 36 | PIXELSORT_INPUT = 0, 37 | PIXELSORT_BRIGHTNESS, 38 | PIXELSORT_X, 39 | PIXELSORT_Y, 40 | PIXELSORT_NUM_PARAMS 41 | }; 42 | 43 | #include "AEPixelSort.h" 44 | 45 | extern "C" DllExport PF_Err EntryPointFunc (PF_Cmd cmd,PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output); 46 | 47 | static PF_Err About(PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output) { 48 | PF_SPRINTF(out_data->return_msg,"PixelSort, v1.0\rKim Asendorf's PixelSort for After Effects"); 49 | 50 | return PF_Err_NONE; 51 | } 52 | 53 | static PF_Err GlobalSetup(PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output) { 54 | 55 | PF_Err err = PF_Err_NONE; 56 | 57 | out_data->my_version = PF_VERSION(2,0,0,PF_Stage_DEVELOP,1); 58 | 59 | out_data->out_flags = PF_OutFlag_I_EXPAND_BUFFER|PF_OutFlag_I_HAVE_EXTERNAL_DEPENDENCIES; 60 | out_data->out_flags2 = PF_OutFlag2_NONE; 61 | 62 | in_data->sequence_data = out_data->sequence_data = nullptr; 63 | 64 | return err; 65 | } 66 | 67 | static PF_Err ParamsSetup(PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output) { 68 | 69 | PF_Err err = PF_Err_NONE; 70 | PF_ParamDef def; 71 | 72 | AEFX_CLR_STRUCT(def); 73 | PF_ADD_CHECKBOX("Brightness Mode","",FALSE,0,PIXELSORT_BRIGHTNESS); 74 | 75 | AEFX_CLR_STRUCT(def); 76 | PF_ADD_SLIDER("X",0,255,0,255,0,PIXELSORT_X); 77 | 78 | AEFX_CLR_STRUCT(def); 79 | PF_ADD_SLIDER("Y",0,255,0,255,0,PIXELSORT_Y); 80 | 81 | out_data->num_params = PIXELSORT_NUM_PARAMS; 82 | 83 | return err; 84 | } 85 | 86 | static PF_Err SequenceSetup(PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output) { 87 | 88 | return PF_Err_NONE; 89 | } 90 | 91 | static PF_Err SequenceSetdown(PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output) { 92 | 93 | return PF_Err_NONE; 94 | } 95 | 96 | static PF_Err SequenceResetup(PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output) { 97 | 98 | return PF_Err_NONE; 99 | } 100 | 101 | static PF_Err Render(PF_InData *in_data,PF_OutData *out_data, PF_ParamDef *params[],PF_LayerDef *output) { 102 | 103 | AEPixelSort::render(¶ms[0]->u.ld,output,params); 104 | 105 | return PF_Err_NONE; 106 | } 107 | 108 | DllExport PF_Err EntryPointFunc(PF_Cmd cmd,PF_InData *in_data,PF_OutData *out_data,PF_ParamDef *params[],PF_LayerDef *output) { 109 | 110 | PF_Err err = PF_Err_NONE; 111 | 112 | switch (cmd) { 113 | case PF_Cmd_ABOUT: err = About(in_data,out_data,params,output); break; 114 | case PF_Cmd_GLOBAL_SETUP: err = GlobalSetup(in_data,out_data,params,output); break; 115 | case PF_Cmd_PARAMS_SETUP: err = ParamsSetup(in_data,out_data,params,output); break; 116 | case PF_Cmd_SEQUENCE_SETUP: err = SequenceSetup(in_data,out_data,params,output); break; 117 | case PF_Cmd_SEQUENCE_SETDOWN: err = SequenceSetdown(in_data,out_data,params,output); break; 118 | case PF_Cmd_SEQUENCE_RESETUP: err = SequenceResetup(in_data,out_data,params,output); break; 119 | case PF_Cmd_RENDER: err = Render(in_data,out_data,params,output); break; 120 | } 121 | return err; 122 | } 123 | 124 | #ifdef AE_OS_WIN 125 | BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) { 126 | 127 | HINSTANCE my_instance_handle = (HINSTANCE)0; 128 | 129 | switch (dwReason) { 130 | case DLL_PROCESS_ATTACH: my_instance_handle = hDLL; break; 131 | case DLL_THREAD_ATTACH: my_instance_handle = hDLL; break; 132 | case DLL_THREAD_DETACH: my_instance_handle = 0; break; 133 | case DLL_PROCESS_DETACH: my_instance_handle = 0; break; 134 | } 135 | return(TRUE); 136 | } 137 | #endif 138 | 139 | -------------------------------------------------------------------------------- /src/AEPixelSort.h: -------------------------------------------------------------------------------- 1 | namespace AEPixelSort { 2 | 3 | // https://ja.wikipedia.org/wiki/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%BD%E3%83%BC%E3%83%88 4 | 5 | inline unsigned int med3(unsigned int x, unsigned int y, unsigned int z) { 6 | if(x>1)],a[j]); 22 | while(1) { 23 | while(a[i] < pivot) i++; 24 | while(pivot < a[j]) j--; 25 | if(i >= j) break; 26 | tmp = a[i]; a[i] = a[j]; a[j] = tmp; 27 | i++; j--; 28 | } 29 | quicksort(a,left,i-1); 30 | quicksort(a,j+1,right); 31 | } 32 | } 33 | 34 | class Buffer { 35 | private: 36 | 37 | unsigned int *_data = nullptr; 38 | unsigned int _length = 0; 39 | 40 | void free() { 41 | if(_data!=nullptr) { 42 | delete[] _data; 43 | _data = nullptr; 44 | } 45 | } 46 | 47 | public: 48 | 49 | Buffer() {} 50 | 51 | unsigned int *data() { return _data; } 52 | unsigned int length() { return _length; } 53 | 54 | void realloc(unsigned int len) { 55 | 56 | if(len>_length) { 57 | 58 | this->free(); 59 | _length = len; 60 | _data = new unsigned int[_length]; 61 | } 62 | } 63 | 64 | ~Buffer() { 65 | this->free(); 66 | } 67 | }; 68 | 69 | class Object { 70 | 71 | private: 72 | 73 | unsigned int _width = 0; 74 | unsigned int _height = 0; 75 | 76 | Buffer *_buffer = new Buffer(); 77 | Buffer *_line = new Buffer(); 78 | 79 | Object() { 80 | } 81 | 82 | Object(const Object &p) {} 83 | virtual ~Object() {} 84 | 85 | public: 86 | 87 | unsigned int *buffer() { return _buffer->data(); }; 88 | unsigned int *line() { return _line->data(); }; 89 | 90 | void sort(int left, int right) { 91 | quicksort(_line->data(),left,right); 92 | } 93 | 94 | void setup(int width,int height) { 95 | _buffer->realloc(width*height); 96 | _line->realloc(width>height?width:height); 97 | } 98 | 99 | unsigned int width() { 100 | return _width; 101 | } 102 | 103 | unsigned int height() { 104 | return _height; 105 | } 106 | 107 | static Object *getInstance() { 108 | static Object instance; 109 | return &instance; 110 | } 111 | }; 112 | 113 | Object *$() { 114 | return Object::getInstance(); 115 | } 116 | 117 | // A C implementation of Kim Asendorf's PixelSort 118 | // https://github.com/kimasendorf/ASDFPixelSort 119 | 120 | 121 | inline unsigned int gris(unsigned char r,unsigned char g,unsigned char b) { 122 | unsigned char tmp = (306*r+601*g+116*b)>>10; 123 | return tmp<<16|tmp<<8|tmp; 124 | } 125 | 126 | void render(PF_EffectWorld *input,PF_LayerDef *output,PF_ParamDef *params[]) { 127 | 128 | bool isBrightness = ((PF_Boolean)params[PIXELSORT_BRIGHTNESS]->u.bd.value==TRUE)?true:false; 129 | unsigned int x = params[PIXELSORT_X]->u.sd.value; 130 | unsigned int y = params[PIXELSORT_Y]->u.sd.value; 131 | 132 | x |= x<<16|x<<8; 133 | y |= y<<16|y<<8; 134 | 135 | int width = output->width; 136 | int height = output->height; 137 | 138 | 139 | unsigned int *src = (unsigned int *)input->data; 140 | int srcRow = input->rowbytes>>2; 141 | 142 | unsigned int *dst = (unsigned int *)output->data; 143 | int dstRow = output->rowbytes>>2; 144 | 145 | 146 | if(x==0&&y==0) { 147 | 148 | for(int i=0; isetup(width,height); 157 | 158 | unsigned int bgr = 0; 159 | unsigned int tmp = 0; 160 | 161 | int then = 0; 162 | bool state = false; 163 | 164 | unsigned char r; 165 | unsigned char g; 166 | unsigned char b; 167 | 168 | unsigned int *line = AEPixelSort::$()->line(); 169 | 170 | if(y) { 171 | 172 | if(x) { 173 | dst = AEPixelSort::$()->buffer(); 174 | dstRow = width; 175 | } 176 | 177 | 178 | for(int j=0; j>8; 186 | 187 | r = bgr&0xFF; 188 | g = (bgr&0xFF00)>>8; 189 | b = (bgr>>16); 190 | 191 | tmp = line[i] = r<<16|g<<8|b; 192 | if(isBrightness) { 193 | tmp = gris(r,b,g); 194 | } 195 | 196 | if(state) { 197 | if(tmp>y) { 198 | AEPixelSort::$()->sort(then,i); 199 | state = false; 200 | } 201 | } 202 | else { 203 | if(tmpsort(then,height); 211 | 212 | for(int i=0; i>16)|(tmp&0xFF00)|((tmp&0xFF)<<16))<<8)|0xFF; 215 | } 216 | } 217 | } 218 | 219 | if(x) { 220 | 221 | if(y) { 222 | src = AEPixelSort::$()->buffer(); 223 | srcRow = width; 224 | } 225 | 226 | dst = (unsigned int *)output->data; 227 | dstRow = output->rowbytes>>2; 228 | 229 | for(int i=0; i>8; 237 | 238 | r = bgr&0xFF; 239 | g = (bgr&0xFF00)>>8; 240 | b = (bgr>>16); 241 | tmp = line[j] = r<<16|g<<8|b; 242 | if(isBrightness) { 243 | tmp = gris(r,b,g); 244 | } 245 | 246 | if(state) { 247 | if(tmp>x) { 248 | AEPixelSort::$()->sort(then,j); 249 | state = false; 250 | } 251 | } 252 | else { 253 | if(tmpsort(then,width); 261 | 262 | for(int j=0; j>16)|(tmp&0xFF00)|((tmp&0xFF)<<16))<<8)|0xFF; 265 | } 266 | } 267 | } 268 | } 269 | } 270 | } 271 | --------------------------------------------------------------------------------