Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7b2c287 authored by John Hoford's avatar John Hoford
Browse files

Add Shadow feature

bug:7234321
Change-Id: Ib0d4db773486e469ed818385b68b7b907070c297
parent 45e666c6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ LOCAL_SRC_FILES := filters/bw.c \
                   filters/exposure.c \
                   filters/contrast.c \
                   filters/hue.c \
                   filters/shadows.c \
                   filters/hsv.c \
		   filters/vignette.c

LOCAL_CFLAGS    += -ffast-math -O3 -funroll-loops
+3 −0
Original line number Diff line number Diff line
@@ -45,4 +45,7 @@ typedef unsigned int Color;

__inline__ unsigned char  clamp(int c);

extern void rgb2hsv( unsigned char *rgb,int rgbOff,unsigned short *hsv,int hsvOff);
extern void hsv2rgb(unsigned short *hsv,int hsvOff,unsigned char  *rgb,int rgbOff);

#endif // FILTERS_H

jni/filters/hsv.c

0 → 100644
+144 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <math.h>
#include "filters.h"

void rgb2hsv( unsigned char *rgb,int rgbOff,unsigned short *hsv,int hsvOff)
{
      int iMin,iMax,chroma;
      int ABITS = 4;
      int HSCALE = 256;

      int k1=255 << ABITS;
      int k2=HSCALE << ABITS;

      int ri = rgb[rgbOff+0];
      int gi = rgb[rgbOff+1];
      int bi = rgb[rgbOff+2];
      short rv,rs,rh;

      if (ri > gi) {
          iMax = MAX (ri, bi);
          iMin = MIN (gi, bi);
      } else {
          iMax = MAX (gi, bi);
          iMin = MIN (ri, bi);
      }

      chroma = iMax - iMin;
      // set value
      rv = (short)( iMax << ABITS);

      // set saturation
      if (rv == 0)
        rs = 0;
      else
        rs = (short)((k1*chroma)/iMax);

      // set hue
      if (rs == 0)
          rh = 0;
      else {
          if ( ri == iMax ) {
            rh  = (short)( (k2*(6*chroma+gi - bi))/(6*chroma));
            if (rh >= k2) rh -= k2;
          } else if (gi  == iMax)
            rh  = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma));
          else // (bi == iMax )
            rh  = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma));
      }
      hsv[hsvOff+0] = rv;
      hsv[hsvOff+1] = rs;
      hsv[hsvOff+2] = rh;
    }

 void hsv2rgb(unsigned short *hsv,int hsvOff, unsigned char *rgb,int rgbOff)
 {
   int ABITS = 4;
   int HSCALE = 256;
   int m;
   int H,X,ih,is,iv;
   int k1=255<<ABITS;
   int k2=HSCALE<<ABITS;
   int k3=1<<(ABITS-1);
   int rr=0;
   int rg=0;
   int rb=0;
   short cv = hsv[hsvOff+0];
   short cs = hsv[hsvOff+1];
   short ch = hsv[hsvOff+2];

   // set chroma and min component value m
   //chroma = ( cv * cs )/k1;
   //m = cv - chroma;
   m = ((int)cv*(k1 - (int)cs ))/k1;

   // chroma  == 0 <-> cs == 0 --> m=cv
   if (cs == 0) {
       rb = ( rg = ( rr =( cv >> ABITS) ));
   } else {
     ih=(int)ch;
     is=(int)cs;
     iv=(int)cv;

     H = (6*ih)/k2;
     X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ;

     // removing additional bits --> unit8
     X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS;
     m=m >> ABITS;

     // ( chroma + m ) --> cv ;
     cv=(short) (cv >> ABITS);
     switch (H) {
         case 0:
           rr = cv;
           rg = X;
           rb = m;
           break;
         case 1:
           rr = X;
           rg = cv;
           rb = m;
           break;
         case 2:
           rr = m;
           rg = cv;
           rb = X;
           break;
         case 3:
           rr = m;
           rg = X;
           rb = cv;
           break;
         case 4:
           rr = X;
           rg = m;
           rb = cv;
           break;
         case 5:
           rr = cv;
           rg = m ;
           rb = X;
           break;
     }
   }
   rgb[rgbOff+0] =  rr;
   rgb[rgbOff+1] =  rg;
   rgb[rgbOff+2] =  rb;
 }

jni/filters/shadows.c

0 → 100644
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <math.h>
#include "filters.h"

 void JNIFUNCF(ImageFilterShadows, nativeApplyFilter, jobject bitmap, jint width, jint height, jshortArray vlut)
 {
     char* destination = 0;
     AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
     unsigned char * rgb = (unsigned char * )destination;
     int i;
     int len = width * height * 4;
     short* lut = (*env)->GetShortArrayElements(env, vlut,0);
     unsigned short * hsv = (unsigned short *)malloc(3*sizeof(short));
     for (i = 0; i < len; i+=4)
     {
       rgb2hsv(rgb,i,hsv,0);
       hsv[0] = lut[hsv[0]];
       hsv2rgb(hsv,0, rgb,i);
     }

     (*env)->ReleaseShortArrayElements(env, vlut, lut, 0);
     free(lut);
     AndroidBitmap_unlockPixels(env, bitmap);
 }
+3 −3
Original line number Diff line number Diff line
@@ -783,14 +783,14 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
                mImageShow.setVisibility(View.VISIBLE);
                mImageShow.setShowControls(true);
                ImagePreset preset = mImageShow.getImagePreset();
                ImageFilter filter = preset.getFilter("Hue");
                ImageFilter filter = preset.getFilter("Shadows");
                if (filter == null) {
                    ImageFilterHue contrast = new ImageFilterHue();
                    ImageFilterShadows contrast = new ImageFilterShadows();
                    ImagePreset copy = new ImagePreset(preset);
                    copy.add(contrast);
                    copy.setHistoryName(contrast.getName());
                    copy.setIsFx(false);
                    filter = copy.getFilter("Hue");
                    filter = copy.getFilter("Shadows");
                    mImageShow.setImagePreset(copy);
                }
                mImageShow.setCurrentFilter(filter);
Loading