Attachment #306803: Color patch with the SSE2 IFAST intrinsics optimizations for OSX for bug #416157

View | Details | Raw Unified | Return to bug 416157
Collapse All | Expand All

(-)gfx/thebes/public/gfxPlatform.h (+59 lines)
Line     Link Here 
 Lines 44-59    Link Here 
44
44
45
#include "gfxTypes.h"
45
#include "gfxTypes.h"
46
#include "gfxASurface.h"
46
#include "gfxASurface.h"
47
47
48
#ifdef XP_OS2
48
#ifdef XP_OS2
49
#undef OS2EMX_PLAIN_CHAR
49
#undef OS2EMX_PLAIN_CHAR
50
#endif
50
#endif
51
51
52
/* SSE2 Support Defines */
53
54
/* GFX_HAVE_SSE2_INTEL_MNEMONICS means that the platform        */
55
/* architecture supports SSE2 but the processor that we're      */
56
/* running on may or may not have SSE2 capability and means     */
57
/* that we have to check processor capabilities before using    */
58
/* SSE2.                                                        */
59
60
/* GFX_HAVE_SSE2_INTRINSICS means that the platform always      */
61
/* supports SSE2. Mac OSX Intel is an example of this as their  */
62
/* Intel Macs started with the Intel Core Duo processor which   */
63
/* supports SSE2.                                               */
64
65
/* GFX_HAVE_SSE2_INTEL_MNEMONICS and GFX_HAVE_SSE2_INTRINSICS   */
66
/* are mutually exclusive - they should not be both defined at  */
67
/* the same time.                                               */
68
69
#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
70
#define GFX_HAVE_SSE2_INTEL_MNEMONICS
71
#endif
72
73
#if defined(__GNUC__) && defined(__i386__) && defined(XP_MACOSX)
74
#define GFX_HAVE_SSE2_INTRINSICS
75
#endif
76
77
#if defined(GFX_HAVE_SSE2_INTEL_MNEMONICS) && defined(GFX_HAVE_SSE2_INTRINSICS)
78
#error Can't have both GFX_HAVE_SSE2_INTEL_MNEMONICS and GFX_HAVE_SSE2_INTRINSICS
79
#endif
80
81
#ifdef GFX_HAVE_SSE2_INTRINSICS
82
#define GFX_SSE2_ALIGN(a) a __attribute__ ((aligned (16)))
83
#endif
84
85
#ifdef GFX_HAVE_SSE2_INTEL_MNEMONICS
86
#define GFX_SSE2_ALIGN(a) __declspec(align(16)) a
87
#endif
88
89
/* Define GFX_DEFINE_SSE2Present before the include of this file in the module */
90
/* where SSE2Present will be declared.                                         */
91
92
#if defined(GFX_HAVE_SSE2_INTEL_MNEMONICS)
93
#if defined(GFX_DEFINE_SSE2Present)
94
int SSE2Present = 0;
95
#else
96
extern int SSE2Present;
97
#endif /* GFX_DEFINE_SSE2Present */
98
#elif defined(GFX_HAVE_SSE2_INTRINSICS)
99
#define SSE2Present 1
100
#else
101
#define SSE2Present 0
102
#endif
103
52
typedef void* cmsHPROFILE;
104
typedef void* cmsHPROFILE;
53
typedef void* cmsHTRANSFORM;
105
typedef void* cmsHTRANSFORM;
54
106
55
class gfxImageSurface;
107
class gfxImageSurface;
56
class gfxFontGroup;
108
class gfxFontGroup;
57
struct gfxFontStyle;
109
struct gfxFontStyle;
58
110
59
// pref lang id's for font prefs
111
// pref lang id's for font prefs
 Lines 220-235   public: Link Here 
220
     */
272
     */
221
    static cmsHTRANSFORM GetCMSInverseRGBTransform();
273
    static cmsHTRANSFORM GetCMSInverseRGBTransform();
222
274
223
    /**
275
    /**
224
     * Return sRGBA -> output device transform.
276
     * Return sRGBA -> output device transform.
225
     */
277
     */
226
    static cmsHTRANSFORM GetCMSRGBATransform();
278
    static cmsHTRANSFORM GetCMSRGBATransform();
227
279
280
    /**
281
     * Runtime check for SSE2 Support
282
     */
283
#if defined(GFX_HAVE_SSE2_INTEL_MNEMONICS)
284
    static int SSE2Support();
285
#endif
286
228
protected:
287
protected:
229
    gfxPlatform() { }
288
    gfxPlatform() { }
230
    virtual ~gfxPlatform();
289
    virtual ~gfxPlatform();
231
290
232
private:
291
private:
233
    virtual cmsHPROFILE GetPlatformCMSOutputProfile();
292
    virtual cmsHPROFILE GetPlatformCMSOutputProfile();
234
};
293
};
235
294
(-)gfx/thebes/src/gfxPlatform.cpp (+22 lines)
Line     Link Here 
 Lines 30-45    Link Here 
30
 * use your version of this file under the terms of the MPL, indicate your
30
 * use your version of this file under the terms of the MPL, indicate your
31
 * decision by deleting the provisions above and replace them with the notice
31
 * decision by deleting the provisions above and replace them with the notice
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
33
 * the provisions above, a recipient may use your version of this file under
33
 * the provisions above, a recipient may use your version of this file under
34
 * the terms of any one of the MPL, the GPL or the LGPL.
34
 * the terms of any one of the MPL, the GPL or the LGPL.
35
 *
35
 *
36
 * ***** END LICENSE BLOCK ***** */
36
 * ***** END LICENSE BLOCK ***** */
37
37
38
/* This declares SSE2Present = 0 */
39
#define GFX_DEFINE_SSE2Present
40
38
#include "gfxPlatform.h"
41
#include "gfxPlatform.h"
39
42
40
#if defined(XP_WIN)
43
#if defined(XP_WIN)
41
#include "gfxWindowsPlatform.h"
44
#include "gfxWindowsPlatform.h"
42
#elif defined(XP_MACOSX)
45
#elif defined(XP_MACOSX)
43
#include "gfxPlatformMac.h"
46
#include "gfxPlatformMac.h"
44
#include "gfxQuartzFontCache.h"
47
#include "gfxQuartzFontCache.h"
45
#elif defined(MOZ_WIDGET_GTK2)
48
#elif defined(MOZ_WIDGET_GTK2)
 Lines 64-79    Link Here 
64
67
65
#include "cairo.h"
68
#include "cairo.h"
66
#include "lcms.h"
69
#include "lcms.h"
67
70
68
#include "plstr.h"
71
#include "plstr.h"
69
#include "nsIPrefService.h"
72
#include "nsIPrefService.h"
70
#include "nsIPrefBranch.h"
73
#include "nsIPrefBranch.h"
71
74
75
#ifdef GFX_HAVE_SSE2_INTEL_MNEMONICS
76
#include "intrin.h"
77
#endif
78
72
gfxPlatform *gPlatform = nsnull;
79
gfxPlatform *gPlatform = nsnull;
73
int gGlitzState = -1;
80
int gGlitzState = -1;
74
static cmsHPROFILE gCMSOutputProfile = nsnull;
81
static cmsHPROFILE gCMSOutputProfile = nsnull;
75
static cmsHTRANSFORM gCMSRGBTransform = nsnull;
82
static cmsHTRANSFORM gCMSRGBTransform = nsnull;
76
static cmsHTRANSFORM gCMSInverseRGBTransform = nsnull;
83
static cmsHTRANSFORM gCMSInverseRGBTransform = nsnull;
77
static cmsHTRANSFORM gCMSRGBATransform = nsnull;
84
static cmsHTRANSFORM gCMSRGBATransform = nsnull;
78
85
79
// this needs to match the list of pref font.default.xx entries listed in all.js!
86
// this needs to match the list of pref font.default.xx entries listed in all.js!
 Lines 532-539   gfxPlatform::GetCMSRGBATransform() Link Here 
532
539
533
        gCMSRGBATransform = cmsCreateTransform(inProfile, TYPE_RGBA_8,
540
        gCMSRGBATransform = cmsCreateTransform(inProfile, TYPE_RGBA_8,
534
                                               outProfile, TYPE_RGBA_8,
541
                                               outProfile, TYPE_RGBA_8,
535
                                               INTENT_PERCEPTUAL, 0);
542
                                               INTENT_PERCEPTUAL, 0);
536
    }
543
    }
537
544
538
    return gCMSRGBATransform;
545
    return gCMSRGBATransform;
539
}
546
}
547
548
/* SSE2 runtime support check  */
549
550
#ifdef GFX_HAVE_SSE2_INTEL_MNEMONICS
551
int gfxPlatform::SSE2Support()
552
{
553
    int CPUInfo[4];
554
555
    __cpuid(CPUInfo, 1);
556
    if (CPUInfo[3] & (0x1 << 26))
557
        return 1;
558
    else
559
        return 2;
560
}
561
#endif
(-)jpeg/jconfig.h (-10 lines)
Line     Link Here 
 Lines 90-107    Link Here 
90
90
91
#undef TWO_FILE_COMMANDLINE
91
#undef TWO_FILE_COMMANDLINE
92
#undef NEED_SIGNAL_CATCHER
92
#undef NEED_SIGNAL_CATCHER
93
#undef DONT_USE_B_MODE
93
#undef DONT_USE_B_MODE
94
#undef PROGRESS_REPORT
94
#undef PROGRESS_REPORT
95
95
96
#endif /* JPEG_CJPEG_DJPEG */
96
#endif /* JPEG_CJPEG_DJPEG */
97
97
98
/* SSE* alignment support - only use on platforms that support declspec and __attribute__ */
99
100
#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
101
#define ALIGN16_const_vector_short(name) __declspec(align(16)) const short name[8]
102
#define ALIGN16_const_vector_uchar(name) __declspec(align(16)) const unsigned char name[16]
103
#else
104
#define ALIGN16_const_vector_short(name) const short name[8] __attribute__ ((aligned (16)))
105
#define ALIGN16_const_vector_uchar(name) const unsigned char name[16] __attribute__ ((aligned (16)))
106
#endif /* ! XP_WIN32 && _M_IX86 && !__GNUC */
107
(-)jpeg/jdapimin.c (-38 / +4 lines)
Line     Link Here 
 Lines 21-44    Link Here 
21
#include "jpeglib.h"
21
#include "jpeglib.h"
22
22
23
#ifdef HAVE_MMX_INTEL_MNEMONICS
23
#ifdef HAVE_MMX_INTEL_MNEMONICS
24
#include "intrin.h"
24
#include "intrin.h"
25
int MMXAvailable;
25
int MMXAvailable;
26
static int mmxsupport();
26
static int mmxsupport();
27
#endif
27
#endif
28
28
29
#ifdef HAVE_SSE2_INTRINSICS
30
int SSE2Available = 0;
31
#ifdef HAVE_SSE2_INTEL_MNEMONICS
29
#ifdef HAVE_SSE2_INTEL_MNEMONICS
30
int SSE2Available = 0;
32
static int sse2support();
31
static int sse2support();
33
#else
34
static int sse2supportGCC();
35
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
32
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
36
#endif /* HAVE_SSE2_INTRINSICS */
37
33
38
34
39
/*
35
/*
40
 * Initialization of a JPEG decompression object.
36
 * Initialization of a JPEG decompression object.
41
 * The error manager must already be set up (in case memory manager fails).
37
 * The error manager must already be set up (in case memory manager fails).
42
 */
38
 */
43
39
44
GLOBAL(void)
40
GLOBAL(void)
 Lines 46-82   jpeg_CreateDecompress (j_decompress_ptr Link Here 
46
{
42
{
47
  int i;
43
  int i;
48
44
49
#ifdef HAVE_MMX_INTEL_MNEMONICS
45
#ifdef HAVE_MMX_INTEL_MNEMONICS
50
  static int cpuidDetected = 0;
46
  static int cpuidDetected = 0;
51
47
52
  if(!cpuidDetected)
48
  if(!cpuidDetected)
53
  {
49
  {
54
	MMXAvailable = mmxsupport();
50
        MMXAvailable = mmxsupport();
55
51
56
#ifdef HAVE_SSE2_INTEL_MNEMONICS
52
#ifdef HAVE_SSE2_INTEL_MNEMONICS
57
	/* only do the sse2 support check if mmx is supported (so
53
	/* only do the sse2 support check if mmx is supported (so
58
	   we know the processor supports cpuid) */
54
	   we know the processor supports cpuid) */
59
	if (MMXAvailable)
55
	if (MMXAvailable)
60
	    SSE2Available = sse2support();
56
	    SSE2Available = sse2support();
61
#endif
57
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
62
58
63
	cpuidDetected = 1;
59
	cpuidDetected = 1;
64
  }
60
  }
65
#else
66
#ifdef HAVE_SSE2_INTRINSICS
67
  static int cpuidDetected = 0;
68
69
  if(!cpuidDetected) {
70
    SSE2Available = sse2supportGCC();
71
    cpuidDetected = 1;
72
  }
73
74
#endif /* HAVE_SSE2_INTRINSICS */
75
#endif /* HAVE_MMX_INTEL_MNEMONICS */
61
#endif /* HAVE_MMX_INTEL_MNEMONICS */
76
62
77
  /* For debugging purposes, zero the whole master structure.
63
  /* For debugging purposes, zero the whole master structure.
78
   * But error manager pointer is already there, so save and restore it.
64
   * But error manager pointer is already there, so save and restore it.
79
   */
65
   */
80
66
81
  /* Guard against version mismatches between library and caller. */
67
  /* Guard against version mismatches between library and caller. */
82
  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
68
  cinfo->mem = NULL;		/* so jpeg_destroy knows mem mgr not called */
 Lines 447-489   static int mmxsupport() Link Here 
447
  int CPUInfo[4];
433
  int CPUInfo[4];
448
434
449
  __cpuid(CPUInfo, 1);
435
  __cpuid(CPUInfo, 1);
450
  if (CPUInfo[3] & (0x1 << 23))
436
  if (CPUInfo[3] & (0x1 << 23))
451
    return 1;
437
    return 1;
452
  else
438
  else
453
    return 0;
439
    return 0;
454
}
440
}
455
#endif
441
#endif /* HAVE_MMX_INTEL_MNEMONICS */
456
442
457
#ifdef HAVE_SSE2_INTEL_MNEMONICS
443
#ifdef HAVE_SSE2_INTEL_MNEMONICS
458
static int sse2support()
444
static int sse2support()
459
{
445
{
460
  int CPUInfo[4];
446
  int CPUInfo[4];
461
447
462
  __cpuid(CPUInfo, 1);
448
  __cpuid(CPUInfo, 1);
463
  if (CPUInfo[3] & (0x1 << 26))
449
  if (CPUInfo[3] & (0x1 << 26))
464
    return 1;
450
    return 1;
465
  else
451
  else
466
    return 2;
452
    return 2;
467
}
453
}
468
#else
469
#ifdef HAVE_SSE2_INTRINSICS
470
static int sse2supportGCC()
471
{
472
473
  /* Mac Intel started with Core Duo chips which have SSE2 Support */
474
475
#if defined(__GNUC__) && defined(__i386__)
476
#if defined(XP_MACOSX)
477
  return 1;
478
#endif /* XP_MACOSX */
479
#endif /* GNUC && i386 */
480
481
  /* Add checking for SSE2 support for other platforms here */
482
483
  /* We don't have SSE2 intrinsics support */
484
485
  return 2;
486
}
487
#endif /* HAVE_SSE2_INTRINSICS */
488
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
454
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
489
455
(-)jpeg/jdcoefct.c (-3 / +15 lines)
Line     Link Here 
 Lines 40-60   typedef struct { Link Here 
40
   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
40
   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
41
   * and let the entropy decoder write into that workspace each time.
41
   * and let the entropy decoder write into that workspace each time.
42
   * (On 80x86, the workspace is FAR even though it's not really very big;
42
   * (On 80x86, the workspace is FAR even though it's not really very big;
43
   * this is to keep the module interfaces unchanged when a large coefficient
43
   * this is to keep the module interfaces unchanged when a large coefficient
44
   * buffer is necessary.)
44
   * buffer is necessary.)
45
   * In multi-pass modes, this array points to the current MCU's blocks
45
   * In multi-pass modes, this array points to the current MCU's blocks
46
   * within the virtual arrays; it is used only by the input side.
46
   * within the virtual arrays; it is used only by the input side.
47
   */
47
   */
48
  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
48
  SSE2_ALIGN(JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]);
49
49
50
#ifdef D_MULTISCAN_FILES_SUPPORTED
50
#ifdef D_MULTISCAN_FILES_SUPPORTED
51
  /* In multi-pass modes, we need a virtual block array for each component. */
51
  /* In multi-pass modes, we need a virtual block array for each component. */
52
  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
52
  SSE2_ALIGN(jvirt_barray_ptr whole_image[MAX_COMPONENTS]);
53
#endif
53
#endif
54
54
55
#ifdef BLOCK_SMOOTHING_SUPPORTED
55
#ifdef BLOCK_SMOOTHING_SUPPORTED
56
  /* When doing block smoothing, we latch coefficient Al values here */
56
  /* When doing block smoothing, we latch coefficient Al values here */
57
  int * coef_bits_latch;
57
  int * coef_bits_latch;
58
#define SAVED_COEFS  6		/* we save coef_bits[0..5] */
58
#define SAVED_COEFS  6		/* we save coef_bits[0..5] */
59
#endif
59
#endif
60
} my_coef_controller;
60
} my_coef_controller;
 Lines 466-482   decompress_smooth_data (j_decompress_ptr Link Here 
466
  int ci, block_row, block_rows, access_rows;
466
  int ci, block_row, block_rows, access_rows;
467
  JBLOCKARRAY buffer;
467
  JBLOCKARRAY buffer;
468
  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
468
  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
469
  JSAMPARRAY output_ptr;
469
  JSAMPARRAY output_ptr;
470
  JDIMENSION output_col;
470
  JDIMENSION output_col;
471
  jpeg_component_info *compptr;
471
  jpeg_component_info *compptr;
472
  inverse_DCT_method_ptr inverse_DCT;
472
  inverse_DCT_method_ptr inverse_DCT;
473
  boolean first_row, last_row;
473
  boolean first_row, last_row;
474
  JBLOCK workspace;
474
  SSE2_ALIGN(JBLOCK workspace);
475
  int *coef_bits;
475
  int *coef_bits;
476
  JQUANT_TBL *quanttbl;
476
  JQUANT_TBL *quanttbl;
477
  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
477
  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
478
  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
478
  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
479
  int Al, pred;
479
  int Al, pred;
480
480
481
  /* Force some input to be done if we are getting ahead of the input. */
481
  /* Force some input to be done if we are getting ahead of the input. */
482
  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
482
  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
 Lines 718-736   jinit_d_coef_controller (j_decompress_pt Link Here 
718
#else
718
#else
719
    ERREXIT(cinfo, JERR_NOT_COMPILED);
719
    ERREXIT(cinfo, JERR_NOT_COMPILED);
720
#endif
720
#endif
721
  } else {
721
  } else {
722
    /* We only need a single-MCU buffer. */
722
    /* We only need a single-MCU buffer. */
723
    JBLOCKROW buffer;
723
    JBLOCKROW buffer;
724
    int i;
724
    int i;
725
725
726
#ifdef HAVE_SSE2_INTRINSICS
727
    /* Align on 16-byte boundaries for the SSE2 code. */
728
    /* This won't work for 64-bit systems so conditional code it. */
729
730
    PRUptrdiff buffer_shift;
731
732
    buffer_shift = (PRUptrdiff)
733
      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
734
                                  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK) + 15);
735
    buffer = (JBLOCKROW) ((buffer_shift + 15) & ~15);
736
#else
726
    buffer = (JBLOCKROW)
737
    buffer = (JBLOCKROW)
727
      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
738
      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
728
				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
739
				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
740
#endif /* HAVE_SSE2_INTRINSICS */
729
    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
741
    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
730
      coef->MCU_buffer[i] = buffer + i;
742
      coef->MCU_buffer[i] = buffer + i;
731
    }
743
    }
732
    coef->pub.consume_data = dummy_consume_data;
744
    coef->pub.consume_data = dummy_consume_data;
733
    coef->pub.decompress_data = decompress_onepass;
745
    coef->pub.decompress_data = decompress_onepass;
734
    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
746
    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
735
  }
747
  }
736
}
748
}
(-)jpeg/jddctmgr.c (-15 / +29 lines)
Line     Link Here 
 Lines 14-30    Link Here 
14
 * dequantization as well as the IDCT proper.  This module sets up the
14
 * dequantization as well as the IDCT proper.  This module sets up the
15
 * dequantization multiplier table needed by the IDCT routine.
15
 * dequantization multiplier table needed by the IDCT routine.
16
 */
16
 */
17
17
18
#define JPEG_INTERNALS
18
#define JPEG_INTERNALS
19
#include "jinclude.h"
19
#include "jinclude.h"
20
#include "jpeglib.h"
20
#include "jpeglib.h"
21
#include "jdct.h"		/* Private declarations for DCT subsystem */
21
#include "jdct.h"		/* Private declarations for DCT subsystem */
22
#ifdef HAVE_SSE2_INTRINSICS
22
#ifdef HAVE_SSE2_INTEL_MNEMONICS
23
extern int SSE2Available;
23
extern int SSE2Available;
24
#endif
24
#endif
25
25
26
/*
26
/*
27
 * The decompressor input side (jdinput.c) saves away the appropriate
27
 * The decompressor input side (jdinput.c) saves away the appropriate
28
 * quantization table for each component at the start of the first scan
28
 * quantization table for each component at the start of the first scan
29
 * involving that component.  (This is necessary in order to correctly
29
 * involving that component.  (This is necessary in order to correctly
30
 * decode files that reuse Q-table slots.)
30
 * decode files that reuse Q-table slots.)
 Lines 75-98   typedef union { Link Here 
75
#ifdef DCT_ISLOW_SUPPORTED
75
#ifdef DCT_ISLOW_SUPPORTED
76
#define PROVIDE_ISLOW_TABLES
76
#define PROVIDE_ISLOW_TABLES
77
#else
77
#else
78
#ifdef IDCT_SCALING_SUPPORTED
78
#ifdef IDCT_SCALING_SUPPORTED
79
#define PROVIDE_ISLOW_TABLES
79
#define PROVIDE_ISLOW_TABLES
80
#endif
80
#endif
81
#endif
81
#endif
82
82
83
#ifdef HAVE_SSE2_INTEL_MNEMONICS
83
GLOBAL(void)
84
GLOBAL(void)
84
jpeg_idct_islow_sse2 (
85
jpeg_idct_islow_sse2 (
85
	j_decompress_ptr cinfo, 
86
	j_decompress_ptr cinfo, 
86
	jpeg_component_info * compptr,
87
	jpeg_component_info * compptr,
87
	JCOEFPTR coef_block,
88
	JCOEFPTR coef_block,
88
	JSAMPARRAY output_buf, 
89
	JSAMPARRAY output_buf, 
89
	JDIMENSION output_col);
90
	JDIMENSION output_col);
91
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
90
92
93
#ifdef HAVE_SSE2_INTRINSICS
94
jpeg_idct_ifast_sse2 (
95
        j_decompress_ptr cinfo, 
96
        jpeg_component_info * compptr,
97
        JCOEFPTR coef_block,
98
        JSAMPARRAY output_buf, 
99
        JDIMENSION output_col);
100
#endif /* HAVE_SSE2_INTRINSICS */
91
101
92
/*
102
/*
93
 * Prepare for an output pass.
103
 * Prepare for an output pass.
94
 * Here we select the proper IDCT routine for each component and build
104
 * Here we select the proper IDCT routine for each component and build
95
 * a matching multiplier table.
105
 * a matching multiplier table.
96
 */
106
 */
97
107
98
METHODDEF(void)
108
METHODDEF(void)
 Lines 142-172   start_pass (j_decompress_ptr cinfo) Link Here 
142
		method_ptr = jpeg_idct_islow;
152
		method_ptr = jpeg_idct_islow;
143
		method = JDCT_ISLOW;
153
		method = JDCT_ISLOW;
144
		  
154
		  
145
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
155
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
146
	break;
156
	break;
147
#endif
157
#endif
148
#ifdef DCT_IFAST_SUPPORTED
158
#ifdef DCT_IFAST_SUPPORTED
149
      case JDCT_IFAST:
159
      case JDCT_IFAST:
150
#ifdef HAVE_SSE2_INTEL_MNEMONICS
160
#ifdef HAVE_SSE2_INTRINSICS
151
		if (SSE2Available==1) 
161
        method_ptr = jpeg_idct_ifast_sse2;
152
		{
162
        method = JDCT_IFAST;
153
			method_ptr = jpeg_idct_islow_sse2;
154
			method = JDCT_ISLOW;
155
		}
156
		else
157
		{
158
			method_ptr = jpeg_idct_ifast;
159
			method = JDCT_IFAST;
160
		}
161
#else
163
#else
162
		method_ptr = jpeg_idct_ifast;
164
        method_ptr = jpeg_idct_ifast;
163
		method = JDCT_IFAST;
165
        method = JDCT_IFAST;
164
#endif /* HAVE_SSE2_INTEL_MNEMONICS */
166
#endif /* HAVE_SSE2_INTRINSICS */
165
	break;
167
	break;
166
168
167
#endif
169
#endif
168
#ifdef DCT_FLOAT_SUPPORTED
170
#ifdef DCT_FLOAT_SUPPORTED
169
      case JDCT_FLOAT:
171
      case JDCT_FLOAT:
170
	method_ptr = jpeg_idct_float;
172
	method_ptr = jpeg_idct_float;
171
	method = JDCT_FLOAT;
173
	method = JDCT_FLOAT;
172
	break;
174
	break;
 Lines 292-307   jinit_inverse_dct (j_decompress_ptr cinf Link Here 
292
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
294
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
293
				SIZEOF(my_idct_controller));
295
				SIZEOF(my_idct_controller));
294
  cinfo->idct = (struct jpeg_inverse_dct *) idct;
296
  cinfo->idct = (struct jpeg_inverse_dct *) idct;
295
  idct->pub.start_pass = start_pass;
297
  idct->pub.start_pass = start_pass;
296
298
297
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
299
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
298
       ci++, compptr++) {
300
       ci++, compptr++) {
299
    /* Allocate and pre-zero a multiplier table for each component */
301
    /* Allocate and pre-zero a multiplier table for each component */
302
#ifdef HAVE_SSE2_INTRINSICS
303
304
    /* Align dct_table on 16 bytes for SSE2 IDCT IFAST optimization */
305
306
    PRUptrdiff buffer_pointer;
307
308
    buffer_pointer = (PRUptrdiff)
309
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
310
                                  SIZEOF(multiplier_table) + 15);
311
    compptr->dct_table = (void *) ((buffer_pointer + 15) & ~15);
312
#else
300
    compptr->dct_table =
313
    compptr->dct_table =
301
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
314
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
302
				  SIZEOF(multiplier_table));
315
				  SIZEOF(multiplier_table));
316
#endif /* HAVE_SSE2_INTRINSICS */
303
    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
317
    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
304
    /* Mark multiplier table not yet set up for any method */
318
    /* Mark multiplier table not yet set up for any method */
305
    idct->cur_method[ci] = -1;
319
    idct->cur_method[ci] = -1;
306
  }
320
  }
307
}
321
}
(-)jpeg/jidctfst.c (+461 lines)
Line     Link Here 
 Lines 166-181   jpeg_idct_ifast_mmx (j_decompress_ptr ci Link Here 
166
		 JCOEFPTR coef_block,
166
		 JCOEFPTR coef_block,
167
		 JSAMPARRAY output_buf, JDIMENSION output_col);
167
		 JSAMPARRAY output_buf, JDIMENSION output_col);
168
__inline GLOBAL(void)
168
__inline GLOBAL(void)
169
jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr,
169
jpeg_idct_ifast_orig (j_decompress_ptr cinfo, jpeg_component_info * compptr,
170
		 JCOEFPTR coef_block,
170
		 JCOEFPTR coef_block,
171
		 JSAMPARRAY output_buf, JDIMENSION output_col);
171
		 JSAMPARRAY output_buf, JDIMENSION output_col);
172
#endif
172
#endif
173
173
174
#ifdef HAVE_SSE2_INTRINSICS
175
GLOBAL(void)
176
jpeg_idct_ifast_sse2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
177
                 JCOEFPTR coef_block,
178
                 JSAMPARRAY output_buf, JDIMENSION output_col);
179
#endif /* HAVE_SSE2_INTRINSICS */
180
174
GLOBAL(void)
181
GLOBAL(void)
175
jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info * compptr,
182
jpeg_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info * compptr,
176
		 JCOEFPTR coef_block,
183
		 JCOEFPTR coef_block,
177
		 JSAMPARRAY output_buf, JDIMENSION output_col);
184
		 JSAMPARRAY output_buf, JDIMENSION output_col);
178
185
179
186
180
#ifdef HAVE_MMX_INTEL_MNEMONICS
187
#ifdef HAVE_MMX_INTEL_MNEMONICS
181
GLOBAL(void)
188
GLOBAL(void)
 Lines 1642-1650   jpeg_idct_ifast_mmx (j_decompress_ptr ci Link Here 
1642
1649
1643
	movq		[ebx], mm3
1650
	movq		[ebx], mm3
1644
1651
1645
	emms
1652
	emms
1646
	}
1653
	}
1647
}
1654
}
1648
#endif
1655
#endif
1649
1656
1657
#ifdef HAVE_SSE2_INTRINSICS
1658
#include "xmmintrin.h"
1659
#include "emmintrin.h"
1660
1661
/* These values are taken from the decimal shifted left 14. When multiplying */
1662
/* by these constants, we have to shift left the other multiplier so that we */
1663
/* we can use pmulhw which will descale us by the 16 bits.                   */
1664
1665
SSE2_ALIGN(unsigned short SSE2_1_414213562[8]) =
1666
  {23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170};
1667
SSE2_ALIGN(unsigned short SSE2_1_847759065[8]) =
1668
  {30274, 30274, 30274, 30274, 30274, 30274, 30274, 30274};
1669
SSE2_ALIGN(unsigned short SSE2_1_082392200[8]) =
1670
  {17734, 17734, 17734, 17734, 17734, 17734, 17734, 17734};
1671
SSE2_ALIGN(unsigned short SSE2_NEG_0_765366865[8]) =
1672
  {52996, 52996, 52996, 52996, 52996, 52996, 52996, 52996};
1673
1674
/* This following is to compensate for range_limit and is shifted five to */
1675
/* the left as that's what we're scaled for at the time.                  */
1676
1677
SSE2_ALIGN(unsigned short SSE2_ADD_128[8]) =
1678
  {4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096};
1679
1680
/*---------------------------------------------------------------------------*/
1681
1682
inline GLOBAL(void)
1683
     jpeg_idct_ifast_sse2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
1684
                           JCOEFPTR coef_block,
1685
                           JSAMPARRAY output_buf, JDIMENSION output_col)
1686
{
1687
  __m128i row0, row1, row2, row3, row4, row5, row6, row7;
1688
  __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
1689
  __m128i tmp10, tmp11, tmp12, tmp13, z10, z11, z12, z13;
1690
  __m128i xps0, xps1, xps2, xps3, rowa;
1691
  __m128i * quantptr;
1692
  __m128i * coefptr;
1693
  JSAMPROW outptr0, outptr1, outptr2, outptr3, outptr4, outptr5, outptr6, outptr7;
1694
1695
  /* ====================================================================== */
1696
  /* Load registers from the coefficient block                              */
1697
  /* ====================================================================== */
1698
1699
  quantptr = (__m128i *) compptr->dct_table;
1700
  coefptr  = (__m128i *) coef_block;
1701
1702
  row0 = *(coefptr+0);
1703
  row1 = *(coefptr+1);
1704
  row2 = *(coefptr+2);
1705
  row3 = *(coefptr+3);
1706
  row4 = *(coefptr+4);
1707
  row5 = *(coefptr+5);
1708
  row6 = *(coefptr+6);
1709
  row7 = *(coefptr+7);
1710
  row0 = _mm_mullo_epi16(row0, *(quantptr+0));
1711
  row1 = _mm_mullo_epi16(row1, *(quantptr+1));
1712
  row2 = _mm_mullo_epi16(row2, *(quantptr+2));
1713
  row3 = _mm_mullo_epi16(row3, *(quantptr+3));
1714
  row4 = _mm_mullo_epi16(row4, *(quantptr+4));
1715
  row5 = _mm_mullo_epi16(row5, *(quantptr+5));
1716
  row6 = _mm_mullo_epi16(row6, *(quantptr+6));
1717
  row7 = _mm_mullo_epi16(row7, *(quantptr+7));
1718
1719
  /* ====================================================================== */
1720
  /* Inverse Discrete Cosine Transform Column Processing                    */
1721
  /* ====================================================================== */
1722
1723
  /* Even part */
1724
1725
  /*  tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); */
1726
  /*  tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); */
1727
1728
  tmp10 = _mm_add_epi16(row0, row4);
1729
  tmp11 = _mm_sub_epi16(row0, row4);
1730
1731
  /*  tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); */
1732
  /*  tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) */
1733
  /*        - tmp13; */
1734
1735
  tmp13 = _mm_add_epi16(row2, row6);
1736
  tmp12 = _mm_mulhi_epi16(_mm_slli_epi16(_mm_sub_epi16(row2, row6), 2),
1737
                          *((__m128i *) SSE2_1_414213562));
1738
  tmp12 = _mm_sub_epi16(tmp12, tmp13);
1739
1740
  /*  tmp0 = tmp10 + tmp13; */
1741
  /*  tmp3 = tmp10 - tmp13; */
1742
  /*  tmp1 = tmp11 + tmp12; */
1743
  /*  tmp2 = tmp11 - tmp12; */
1744
1745
  tmp0 = _mm_add_epi16(tmp10, tmp13);
1746
  tmp3 = _mm_sub_epi16(tmp10, tmp13);
1747
  tmp1 = _mm_add_epi16(tmp11, tmp12);
1748
  tmp2 = _mm_sub_epi16(tmp11, tmp12);
1749
1750
  /* Odd part */
1751
1752
  /*  z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; */
1753
  /*  z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; */
1754
  /*  z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; */
1755
  /*  z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; */
1756
1757
  z13 = _mm_add_epi16(row5, row3);
1758
  z10 = _mm_sub_epi16(row5, row3);
1759
  z11 = _mm_add_epi16(row1, row7);
1760
  z12 = _mm_sub_epi16(row1, row7);
1761
1762
  /* phase 5 */
1763
1764
  /*  tmp7 = z11 + z13; */
1765
  /*  tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); */
1766
1767
  tmp7 = _mm_add_epi16(z11, z13);
1768
  tmp11 = _mm_mulhi_epi16(_mm_slli_epi16(_mm_sub_epi16(z11, z13), 2),
1769
                          *((__m128i *) SSE2_1_414213562));
1770
1771
  /*  z5 = MULTIPLY(z10 + z12, FIX_1_847759065); */
1772
  /*  tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; */
1773
  /*  tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; */
1774
1775
  /* This is really a mess as the negative 2.61 doesn't work well */
1776
  /* as we're working with 16-bit integers. So we're going to apply */
1777
  /* a little algebra to get: */
1778
1779
  /*  tmp10 = z12 * (FIX_1_082392200 - FIX_1_847759065) - z10*FIX_1_847759065 */
1780
  /*  tmp12 = z10 * (FIX_1_847759065 - FIX_2_613125930) + z12*FIX_1_847759065 */
1781
1782
  /* or */
1783
1784
  /*  tmp10 = z12 * FIX_NEG_0_765366865 - z10 * FIX_1_847759065 */
1785
  /*  tmp12 = z10 * FIX_NEG_0_765366865 + z12 * FIX_1_847759065 */
1786
1787
  z10 = _mm_slli_epi16(z10, 2);
1788
  z12 = _mm_slli_epi16(z12, 2);
1789
1790
  tmp10 = _mm_sub_epi16(_mm_mulhi_epi16(z12, *((__m128i *)SSE2_NEG_0_765366865)),
1791
                        _mm_mulhi_epi16(z10, *((__m128i *)SSE2_1_847759065)));
1792
  tmp12 = _mm_add_epi16(_mm_mulhi_epi16(z10, *((__m128i *)SSE2_NEG_0_765366865)),
1793
                        _mm_mulhi_epi16(z12, *((__m128i *)SSE2_1_847759065)));
1794
1795
  /* phase 2 */
1796
1797
  /*  tmp6 = tmp12 - tmp7; */
1798
  /*  tmp5 = tmp11 - tmp6; */
1799
  /*  tmp4 = tmp10 + tmp5; */
1800
1801
  tmp6 = _mm_sub_epi16(tmp12, tmp7);
1802
  tmp5 = _mm_sub_epi16(tmp11, tmp6);
1803
  tmp4 = _mm_add_epi16(tmp10, tmp5);
1804
1805
  /*  outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)  */
1806
  /*                        & RANGE_MASK]; */
1807
  /*  outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) */
1808
  /*                        & RANGE_MASK]; */
1809
1810
  row0 = _mm_add_epi16(tmp0, tmp7);
1811
  row7 = _mm_sub_epi16(tmp0, tmp7);
1812
1813
  /*  outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) */
1814
  /*                        & RANGE_MASK]; */
1815
  /*  outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) */
1816
  /*                        & RANGE_MASK]; */
1817
1818
  row1 = _mm_add_epi16(tmp1, tmp6);
1819
  row6 = _mm_sub_epi16(tmp1, tmp6);
1820
1821
  /*  outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) */
1822
  /*                        & RANGE_MASK]; */
1823
  /*  outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) */
1824
  /*                        & RANGE_MASK]; */
1825
1826
  row2 = _mm_add_epi16(tmp2, tmp5);
1827
  row5 = _mm_sub_epi16(tmp2, tmp5);
1828
1829
  /*  outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) */
1830
  /*                        & RANGE_MASK]; */
1831
  /*  outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) */
1832
  /*                        & RANGE_MASK]; */
1833
1834
  row4 = _mm_add_epi16(tmp3, tmp4);
1835
  row3 = _mm_sub_epi16(tmp3, tmp4);
1836
1837
  /* ====================================================================== */
1838
  /* Transpose Matrix (Word)                                                */
1839
  /* ====================================================================== */
1840
1841
  /* Save off the low quadwords from the even rows */
1842
1843
  xps0 = _mm_move_epi64(row0);
1844
  xps1 = _mm_move_epi64(row2);
1845
  xps2 = _mm_move_epi64(row4);
1846
  xps3 = _mm_move_epi64(row6);
1847
1848
  /* Interleave the high quadwords */
1849
1850
  row0 = _mm_unpackhi_epi16(row0, row1);    /* 04 14 05 15 06 16 07 17 */
1851
  row2 = _mm_unpackhi_epi16(row2, row3);    /* 24 34 25 35 26 36 27 37 */
1852
  row4 = _mm_unpackhi_epi16(row4, row5);    /* 44 54 45 55 46 56 47 57 */
1853
  row6 = _mm_unpackhi_epi16(row6, row7);    /* 64 74 65 75 66 76 67 77 */ 
1854
1855
  rowa = row0;
1856
  row0 = _mm_unpacklo_epi32(row0, row2);    /* 04 14 24 34 05 15 25 35 */
1857
  rowa = _mm_unpackhi_epi32(rowa, row2);    /* 06 16 26 36 07 17 27 37 */
1858
1859
  row2 = row4;
1860
  row4 = _mm_unpacklo_epi32(row4, row6);    /* 44 54 64 74 45 55 65 75 */
1861
  row2 = _mm_unpackhi_epi32(row2, row6);    /* 46 56 66 76 47 57 67 77 */
1862
1863
  row6 = row0;
1864
  row0 = _mm_unpacklo_epi64(row0, row4);    /* 04 14 24 34 44 54 64 74 */
1865
  row6 = _mm_unpackhi_epi64(row6, row4);    /* 05 15 25 35 45 55 65 75 */
1866
1867
  row4 = rowa;
1868
  rowa = _mm_unpacklo_epi64(rowa, row2);    /* 06 16 26 36 46 56 66 76 */
1869
  row4 = _mm_unpackhi_epi64(row4, row2);    /* 07 17 27 37 47 57 67 77 */
1870
1871
  /* row0, row6, rowa, row4 now contain *4, *5, *6, *7 */
1872
1873
  /* Interleave the low quadwords */
1874
1875
  xps0 = _mm_unpacklo_epi16(xps0, row1);    /* 00 10 01 11 02 12 03 13 */
1876
  xps1 = _mm_unpacklo_epi16(xps1, row3);    /* 20 30 21 31 22 32 23 33 */
1877
  xps2 = _mm_unpacklo_epi16(xps2, row5);    /* 40 50 41 51 42 52 43 43 */
1878
  xps3 = _mm_unpacklo_epi16(xps3, row7);    /* 60 70 61 71 62 72 63 73 */
1879
1880
  row2 = xps0;
1881
  xps0 = _mm_unpacklo_epi32(xps0, xps1);    /* 00 10 20 30 01 11 21 31 */
1882
  row2 = _mm_unpackhi_epi32(row2, xps1);    /* 02 12 22 32 03 13 23 33 */
1883
1884
  xps1 = xps2;
1885
  xps2 = _mm_unpacklo_epi32(xps2, xps3);    /* 40 50 60 70 41 51 61 71 */
1886
  xps1 = _mm_unpackhi_epi32(xps1, xps3);    /* 42 52 62 72 43 53 63 73 */
1887
1888
  xps3 = xps0;
1889
  xps0 = _mm_unpacklo_epi64(xps0, xps2);    /* 00 10 20 30 40 50 60 70 */
1890
  xps3 = _mm_unpackhi_epi64(xps3, xps2);    /* 01 11 21 31 41 51 61 71 */
1891
1892
  xps2 = row2;
1893
  row2 = _mm_unpacklo_epi64(row2, xps1);    /* 02 12 22 32 42 52 62 72 */
1894
  xps2 = _mm_unpackhi_epi64(xps2, xps1);    /* 03 13 23 33 43 53 63 73 */
1895
1896
  /* xps0, xps3, row2, xps2 now contain *0, *1, *2, *3 */
1897
1898
  /* Restructure back to row0 to row7. */
1899
1900
  row7 = row4;
1901
  row5 = row6;
1902
  row6 = rowa;
1903
  row4 = row0;
1904
  row0 = xps0;
1905
  row1 = xps3;
1906
  row3 = xps2;
1907
1908
  /* ====================================================================== */
1909
  /* Inverse Discrete Cosine Transform Row Processing                       */
1910
  /* ====================================================================== */
1911
1912
  /* Even part */
1913
1914
  /*  tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); */
1915
  /*  tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); */
1916
1917
  tmp10 = _mm_add_epi16(row0, row4);
1918
  tmp11 = _mm_sub_epi16(row0, row4);
1919
1920
  /*  tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); */
1921
  /*  tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) */
1922
  /*        - tmp13; */
1923
1924
  tmp13 = _mm_add_epi16(row2, row6);
1925
  tmp12 = _mm_mulhi_epi16(_mm_slli_epi16(_mm_sub_epi16(row2, row6), 2),
1926
                          *((__m128i *) SSE2_1_414213562));
1927
  tmp12 = _mm_sub_epi16(tmp12, tmp13);
1928
1929
  /*  tmp0 = tmp10 + tmp13; */
1930
  /*  tmp3 = tmp10 - tmp13; */
1931
  /*  tmp1 = tmp11 + tmp12; */
1932
  /*  tmp2 = tmp11 - tmp12; */
1933
1934
  tmp0 = _mm_add_epi16(tmp10, tmp13);
1935
  tmp3 = _mm_sub_epi16(tmp10, tmp13);
1936
  tmp1 = _mm_add_epi16(tmp11, tmp12);
1937
  tmp2 = _mm_sub_epi16(tmp11, tmp12);
1938
1939
  /* Odd part */
1940
1941
  /*  z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; */
1942
  /*  z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; */
1943
  /*  z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; */
1944
  /*  z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; */
1945
1946
  z13 = _mm_add_epi16(row5, row3);
1947
  z10 = _mm_sub_epi16(row5, row3);
1948
  z11 = _mm_add_epi16(row1, row7);
1949
  z12 = _mm_sub_epi16(row1, row7);
1950
1951
  /* phase 5 */
1952
1953
  /*  tmp7 = z11 + z13; */
1954
  /*  tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); */
1955
1956
  tmp7 = _mm_add_epi16(z11, z13);
1957
  tmp11 = _mm_mulhi_epi16(_mm_slli_epi16(_mm_sub_epi16(z11, z13), 2),
1958
                          *((__m128i *) SSE2_1_414213562));
1959
1960
  /*  z5 = MULTIPLY(z10 + z12, FIX_1_847759065); */
1961
  /*  tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; */
1962
  /*  tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; */
1963
1964
  /* This is really a mess as the negative 2.61 doesn't work well */
1965
  /* as we're working with 16-bit integers. So we're going to apply */
1966
  /* a little algebra to get: */
1967
1968
  /*  tmp10 = z12 * (FIX_1_082392200 - FIX_1_847759065) - z10*FIX_1_847759065 */
1969
  /*  tmp12 = z10 * (FIX_1_847759065 - FIX_2_613125930) + z12*FIX_1_847759065 */
1970
1971
  /* or */
1972
1973
  /*  tmp10 = z12 * FIX_NEG_0_765366865 - z10 * FIX_1_847759065 */
1974
  /*  tmp12 = z10 * FIX_NEG_0_765366865 + z12 * FIX_1_847759065 */
1975
1976
  z10 = _mm_slli_epi16(z10, 2);
1977
  z12 = _mm_slli_epi16(z12, 2);
1978
1979
  tmp10 = _mm_sub_epi16(_mm_mulhi_epi16(z12, *((__m128i *)SSE2_NEG_0_765366865)),
1980
                        _mm_mulhi_epi16(z10, *((__m128i *)SSE2_1_847759065)));
1981
  tmp12 = _mm_add_epi16(_mm_mulhi_epi16(z10, *((__m128i *)SSE2_NEG_0_765366865)),
1982
                        _mm_mulhi_epi16(z12, *((__m128i *)SSE2_1_847759065)));
1983
1984
  /* phase 2 */
1985
1986
  /*  tmp6 = tmp12 - tmp7; */
1987
  /*  tmp5 = tmp11 - tmp6; */
1988
  /*  tmp4 = tmp10 + tmp5; */
1989
1990
  tmp6 = _mm_sub_epi16(tmp12, tmp7);
1991
  tmp5 = _mm_sub_epi16(tmp11, tmp6);
1992
  tmp4 = _mm_add_epi16(tmp10, tmp5);
1993
1994
  /*  outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)  */
1995
  /*                        & RANGE_MASK]; */
1996
  /*  outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) */
1997
  /*                        & RANGE_MASK]; */
1998
1999
  row0 = _mm_add_epi16(tmp0, tmp7);
2000
  row7 = _mm_sub_epi16(tmp0, tmp7);
2001
2002
  /*  outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) */
2003
  /*                        & RANGE_MASK]; */
2004
  /*  outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) */
2005
  /*                        & RANGE_MASK]; */
2006
2007
  row1 = _mm_add_epi16(tmp1, tmp6);
2008
  row6 = _mm_sub_epi16(tmp1, tmp6);
2009
2010
  /*  outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) */
2011
  /*                        & RANGE_MASK]; */
2012
  /*  outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) */
2013
  /*                        & RANGE_MASK]; */
2014
2015
  row2 = _mm_add_epi16(tmp2, tmp5);
2016
  row5 = _mm_sub_epi16(tmp2, tmp5);
2017
2018
  /*  outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) */
2019
  /*                        & RANGE_MASK]; */
2020
  /*  outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) */
2021
  /*                        & RANGE_MASK]; */
2022
2023
  row4 = _mm_add_epi16(tmp3, tmp4);
2024
  row3 = _mm_sub_epi16(tmp3, tmp4);
2025
2026
  /* ====================================================================== */
2027
  /* Transpose Matrix (Byte)                                                */
2028
  /* ====================================================================== */
2029
2030
  /* Shift right after adding half to descale */
2031
2032
  row0 = _mm_add_epi16(row0, *((__m128i *) SSE2_ADD_128));
2033
  row1 = _mm_add_epi16(row1, *((__m128i *) SSE2_ADD_128));
2034
  row2 = _mm_add_epi16(row2, *((__m128i *) SSE2_ADD_128));
2035
  row3 = _mm_add_epi16(row3, *((__m128i *) SSE2_ADD_128));
2036
  row4 = _mm_add_epi16(row4, *((__m128i *) SSE2_ADD_128));
2037
  row5 = _mm_add_epi16(row5, *((__m128i *) SSE2_ADD_128));
2038
  row6 = _mm_add_epi16(row6, *((__m128i *) SSE2_ADD_128));
2039
  row7 = _mm_add_epi16(row7, *((__m128i *) SSE2_ADD_128));
2040
2041
  row0 = _mm_srai_epi16(row0, 5);
2042
  row1 = _mm_srai_epi16(row1, 5);
2043
  row2 = _mm_srai_epi16(row2, 5);
2044
  row3 = _mm_srai_epi16(row3, 5);
2045
  row4 = _mm_srai_epi16(row4, 5);
2046
  row5 = _mm_srai_epi16(row5, 5);
2047
  row6 = _mm_srai_epi16(row6, 5);
2048
  row7 = _mm_srai_epi16(row7, 5);
2049
2050
  /* Range Limit and convert Words to Bytes */
2051
2052
  row0 = _mm_packus_epi16(row0, row4);
2053
  row1 = _mm_packus_epi16(row1, row5);
2054
  row2 = _mm_packus_epi16(row2, row6);
2055
  row3 = _mm_packus_epi16(row3, row7);
2056
2057
  /* Transpose from rows back to columns */
2058
2059
  row4 = _mm_unpackhi_epi8(row0, row1);   /* 40 50 41 51 42 52 43 43 ... */
2060
  row5 = _mm_unpackhi_epi8(row2, row3);   /* 60 70 61 71 62 72 63 73 ... */
2061
  row0 = _mm_unpacklo_epi8(row0, row1);   /* 00 10 01 11 02 12 03 13 ... */
2062
  row2 = _mm_unpacklo_epi8(row2, row3);   /* 20 30 21 31 22 32 23 33 ... */
2063
2064
  row6 = _mm_unpackhi_epi16(row0, row2);  /* 04 14 24 34 05 15 25 35 ... */
2065
  row7 = _mm_unpackhi_epi16(row4, row5);  /* 44 54 64 74 45 55 65 75 ... */
2066
  row0 = _mm_unpacklo_epi16(row0, row2);  /* 00 10 20 30 01 11 21 31 ... */
2067
  row4 = _mm_unpacklo_epi16(row4, row5);  /* 40 50 60 70 41 51 61 71 ... */
2068
2069
  row1 = _mm_unpackhi_epi32(row0, row4);  /* 02 12 22 32 42 52 62 72 ... */
2070
  row2 = _mm_unpackhi_epi32(row6, row7);  /* 06 16 26 36 46 56 66 76 ... */
2071
  row0 = _mm_unpacklo_epi32(row0, row4);  /* 00 10 20 30 40 50 60 70 ... */
2072
  row6 = _mm_unpacklo_epi32(row6, row7);  /* 04 14 24 34 55 54 64 74 ... */
2073
2074
  /* Rearrange for readability */
2075
2076
  row3 = row2;
2077
  row2 = row6;
2078
2079
  /* ====================================================================== */
2080
  /* Final output                                                           */
2081
  /* ====================================================================== */
2082
2083
  outptr0 = output_buf[0] + output_col;
2084
  outptr1 = output_buf[1] + output_col;
2085
  outptr2 = output_buf[2] + output_col;
2086
  outptr3 = output_buf[3] + output_col;
2087
  outptr4 = output_buf[4] + output_col;
2088
  outptr5 = output_buf[5] + output_col;
2089
  outptr6 = output_buf[6] + output_col;
2090
  outptr7 = output_buf[7] + output_col;
2091
2092
  /* We can't use the faster FP instructions to write out the high quad */
2093
  /* so do a rotate right and write them out as the low quad            */
2094
2095
  row4 = _mm_srli_si128(row0, 8);
2096
  row5 = _mm_srli_si128(row1, 8);
2097
  row6 = _mm_srli_si128(row2, 8);
2098
  row7 = _mm_srli_si128(row3, 8);
2099
2100
  _mm_storel_epi64((__m128i *) outptr0, row0);
2101
  _mm_storel_epi64((__m128i *) outptr2, row1);
2102
  _mm_storel_epi64((__m128i *) outptr4, row2);
2103
  _mm_storel_epi64((__m128i *) outptr6, row3);
2104
  _mm_storel_epi64((__m128i *) outptr1, row4);
2105
  _mm_storel_epi64((__m128i *) outptr3, row5);
2106
  _mm_storel_epi64((__m128i *) outptr5, row6);
2107
  _mm_storel_epi64((__m128i *) outptr7, row7);
2108
}
2109
#endif /* HAVE_SSE2_INTRINSICS */
2110
1650
#endif /* DCT_IFAST_SUPPORTED */
2111
#endif /* DCT_IFAST_SUPPORTED */
(-)jpeg/jmemmgr.c (+10 lines)
Line     Link Here 
 Lines 444-459   alloc_barray (j_common_ptr cinfo, int po Link Here 
444
	      JDIMENSION blocksperrow, JDIMENSION numrows)
444
	      JDIMENSION blocksperrow, JDIMENSION numrows)
445
/* Allocate a 2-D coefficient-block array */
445
/* Allocate a 2-D coefficient-block array */
446
{
446
{
447
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
447
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
448
  JBLOCKARRAY result;
448
  JBLOCKARRAY result;
449
  JBLOCKROW workspace;
449
  JBLOCKROW workspace;
450
  JDIMENSION rowsperchunk, currow, i;
450
  JDIMENSION rowsperchunk, currow, i;
451
  long ltemp;
451
  long ltemp;
452
#ifdef HAVE_SSE2_INTRINSICS
453
  PRUptrdiff workspace_raw;
454
#endif
452
455
453
  /* Calculate max # of rows allowed in one allocation chunk */
456
  /* Calculate max # of rows allowed in one allocation chunk */
454
  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
457
  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
455
	  ((long) blocksperrow * SIZEOF(JBLOCK));
458
	  ((long) blocksperrow * SIZEOF(JBLOCK));
456
  if (ltemp <= 0)
459
  if (ltemp <= 0)
457
    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
460
    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
458
  if (ltemp < (long) numrows)
461
  if (ltemp < (long) numrows)
459
    rowsperchunk = (JDIMENSION) ltemp;
462
    rowsperchunk = (JDIMENSION) ltemp;
 Lines 464-482   alloc_barray (j_common_ptr cinfo, int po Link Here 
464
  /* Get space for row pointers (small object) */
467
  /* Get space for row pointers (small object) */
465
  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
468
  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
466
				     (size_t) (numrows * SIZEOF(JBLOCKROW)));
469
				     (size_t) (numrows * SIZEOF(JBLOCKROW)));
467
470
468
  /* Get the rows themselves (large objects) */
471
  /* Get the rows themselves (large objects) */
469
  currow = 0;
472
  currow = 0;
470
  while (currow < numrows) {
473
  while (currow < numrows) {
471
    rowsperchunk = MIN(rowsperchunk, numrows - currow);
474
    rowsperchunk = MIN(rowsperchunk, numrows - currow);
475
#ifdef HAVE_SSE2_INTRINSICS
476
    workspace_raw = (JBLOCKROW) alloc_large(cinfo, pool_id,
477
        (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
478
                  * SIZEOF(JBLOCK) + 15));
479
    workspace = (JBLOCKROW) ((workspace_raw + 15) & ~15);
480
#else
472
    workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
481
    workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
473
	(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
482
	(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
474
		  * SIZEOF(JBLOCK)));
483
		  * SIZEOF(JBLOCK)));
484
#endif /* HAVE_SSE2_INTRINSICS */
475
    for (i = rowsperchunk; i > 0; i--) {
485
    for (i = rowsperchunk; i > 0; i--) {
476
      result[currow++] = workspace;
486
      result[currow++] = workspace;
477
      workspace += blocksperrow;
487
      workspace += blocksperrow;
478
    }
488
    }
479
  }
489
  }
480
490
481
  return result;
491
  return result;
482
}
492
}
(-)jpeg/jmorecfg.h (-9 / +17 lines)
Line     Link Here 
 Lines 102-133   typedef short JSAMPLE; Link Here 
102
 * Again, we allocate large arrays of these, but you can change to int
102
 * Again, we allocate large arrays of these, but you can change to int
103
 * if you have memory to burn and "short" is really slow.
103
 * if you have memory to burn and "short" is really slow.
104
 */
104
 */
105
105
106
typedef short JCOEF;
106
typedef short JCOEF;
107
107
108
/* Defines for MMX/SSE2 support. */
108
/* Defines for MMX/SSE2 support. */
109
109
110
#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
110
/* HAVE_SSE2_INTEL_MNEMONICS means Win32 and MSVC. HAVE_SSE2_INTRINSICS */
111
#define HAVE_MMX_INTEL_MNEMONICS 
111
/* means that the platform supports SSE2 or higher so that we don't     */
112
/* have to check runtime CPU capabilities.                              */
112
113
113
/* SSE2 code appears broken for some cpus (bug 247437) */
114
#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
115
#define HAVE_MMX_INTEL_MNEMONICS
114
#define HAVE_SSE2_INTEL_MNEMONICS
116
#define HAVE_SSE2_INTEL_MNEMONICS
115
#define HAVE_SSE2_INTRINSICS
116
#endif
117
#endif
117
118
118
#if defined(__GNUC__) && defined(__i386__)
119
#if defined(__GNUC__) && defined(__i386__) && defined(XP_MACOSX)
119
#if defined(XP_MACOSX)
120
#define HAVE_SSE2_INTRINSICS
120
#define HAVE_SSE2_INTRINSICS
121
#endif /* ! XP_MACOSX */
121
#endif /* GNUC && i386 && XP_MACOSX */
122
#endif /* ! GNUC && i386 */
123
122
124
/* Add support for other platforms here */
123
/* Add support for other platforms here */
125
124
125
/* SSE* alignment support - only use on platforms that support declspec and __attribute__ */
126
/* We're only aligning Mac OSX structures right now */
127
128
#ifdef HAVE_SSE2_INTRINSICS
129
#define SSE2_ALIGN(a) a __attribute__ ((aligned (16)))
130
#else
131
#define SSE2_ALIGN(a) a
132
#endif
133
126
134
127
/* Compressed datastreams are represented as arrays of JOCTET.
135
/* Compressed datastreams are represented as arrays of JOCTET.
128
 * These must be EXACTLY 8 bits wide, at least once they are written to
136
 * These must be EXACTLY 8 bits wide, at least once they are written to
129
 * external storage.  Note that when using the stdio data source/destination
137
 * external storage.  Note that when using the stdio data source/destination
130
 * managers, this is also the data type passed to fread/fwrite.
138
 * managers, this is also the data type passed to fread/fwrite.
131
 */
139
 */
132
140
133
#ifdef HAVE_UNSIGNED_CHAR
141
#ifdef HAVE_UNSIGNED_CHAR
 Lines 315-331   typedef unsigned char boolean; Link Here 
315
 * QUANT_1PASS_SUPPORTED QUANT_2PASS_SUPPORTED
323
 * QUANT_1PASS_SUPPORTED QUANT_2PASS_SUPPORTED
316
 */
324
 */
317
325
318
/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
326
/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
319
327
320
/* Capability options common to encoder and decoder: */
328
/* Capability options common to encoder and decoder: */
321
329
322
#define DCT_ISLOW_SUPPORTED	/* slow but accurate integer algorithm */
330
#define DCT_ISLOW_SUPPORTED	/* slow but accurate integer algorithm */
323
#undef  DCT_IFAST_SUPPORTED	/* faster, less accurate integer method */
331
#define DCT_IFAST_SUPPORTED     /* faster, less accurate integer method */
324
#undef  DCT_FLOAT_SUPPORTED	/* floating-point: accurate, fast on fast HW */
332
#undef  DCT_FLOAT_SUPPORTED	/* floating-point: accurate, fast on fast HW */
325
333
326
/* Encoder capability options: */
334
/* Encoder capability options: */
327
335
328
#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
336
#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
329
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
337
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
330
#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
338
#define C_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
331
#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
339
#define ENTROPY_OPT_SUPPORTED	    /* Optimization of entropy coding parms? */
(-)modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp (-18 / +151 lines)
Line     Link Here 
 Lines 51-66    Link Here 
51
#include "nsIImage.h"
51
#include "nsIImage.h"
52
#include "nsIInterfaceRequestorUtils.h"
52
#include "nsIInterfaceRequestorUtils.h"
53
#include "gfxColor.h"
53
#include "gfxColor.h"
54
54
55
#include "jerror.h"
55
#include "jerror.h"
56
56
57
#include "gfxPlatform.h"
57
#include "gfxPlatform.h"
58
58
59
#if defined(GFX_HAVE_SSE2_INTEL_MNEMONICS) || defined(GFX_HAVE_SSE2_INTRINSICS)
60
#include "emmintrin.h"
61
#endif /* GFX_HAVE_SSE2_INTEL_MNEMONICS || GFX_HAVE_SSE2_INTRINSICS */
62
59
extern "C" {
63
extern "C" {
60
#include "iccjpeg.h"
64
#include "iccjpeg.h"
61
65
62
/* Colorspace conversion (copied from jpegint.h) */
66
/* Colorspace conversion (copied from jpegint.h) */
63
struct jpeg_color_deconverter {
67
struct jpeg_color_deconverter {
64
  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
68
  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
65
  JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
69
  JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
66
				JSAMPIMAGE input_buf, JDIMENSION input_row,
70
				JSAMPIMAGE input_buf, JDIMENSION input_row,
 Lines 519-535   nsresult nsJPEGDecoder::ProcessData(cons Link Here 
519
  case JPEG_START_DECOMPRESS:
523
  case JPEG_START_DECOMPRESS:
520
  {
524
  {
521
    LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::ProcessData -- entering JPEG_START_DECOMPRESS case");
525
    LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::ProcessData -- entering JPEG_START_DECOMPRESS case");
522
    /* Step 4: set parameters for decompression */
526
    /* Step 4: set parameters for decompression */
523
527
524
    /* FIXME -- Should reset dct_method and dither mode
528
    /* FIXME -- Should reset dct_method and dither mode
525
     * for final pass of progressive JPEG
529
     * for final pass of progressive JPEG
526
     */
530
     */
531
#ifdef GFX_HAVE_SSE2_INTRINSICS
532
    mInfo.dct_method =  JDCT_IFAST;
533
#else
527
    mInfo.dct_method =  JDCT_ISLOW;
534
    mInfo.dct_method =  JDCT_ISLOW;
535
#endif /* GFX_HAVE_SSE2_INTRINSICS */
528
    mInfo.dither_mode = JDITHER_FS;
536
    mInfo.dither_mode = JDITHER_FS;
529
    mInfo.do_fancy_upsampling = TRUE;
537
    mInfo.do_fancy_upsampling = TRUE;
530
    mInfo.enable_2pass_quant = FALSE;
538
    mInfo.enable_2pass_quant = FALSE;
531
    mInfo.do_block_smoothing = TRUE;
539
    mInfo.do_block_smoothing = TRUE;
532
540
533
    /* Step 5: Start decompressor */
541
    /* Step 5: Start decompressor */
534
    if (jpeg_start_decompress(&mInfo) == FALSE) {
542
    if (jpeg_start_decompress(&mInfo) == FALSE) {
535
      PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
543
      PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
 Lines 1245-1294   const int Cb_g_tab[(MAXJSAMPLE+1) * size Link Here 
1245
	((shift_temp = (x)) < 0 ? \
1253
	((shift_temp = (x)) < 0 ? \
1246
	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
1254
	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
1247
	 (shift_temp >> (shft)))
1255
	 (shift_temp >> (shft)))
1248
#else
1256
#else
1249
#define SHIFT_TEMPS
1257
#define SHIFT_TEMPS
1250
#define RIGHT_SHIFT(x,shft)	((x) >> (shft))
1258
#define RIGHT_SHIFT(x,shft)	((x) >> (shft))
1251
#endif
1259
#endif
1252
1260
1261
/* Constants for SSE2 support */
1262
1263
GFX_SSE2_ALIGN(const short color_constants_1[8]) = {128, 128, 128, 128, 128, 128, 128, 128};
1264
GFX_SSE2_ALIGN(const short color_constants_2[8]) = {359, 359, 359, 359, 359, 359, 359, 359};
1265
GFX_SSE2_ALIGN(const short color_constants_3[8]) = {88, 88, 88, 88, 88, 88, 88, 88};
1266
GFX_SSE2_ALIGN(const short color_constants_4[8]) = {183, 183, 183, 183, 183, 183, 183, 183};
1267
GFX_SSE2_ALIGN(const short color_constants_5[8]) = {454, 454, 454, 454, 454, 454, 454, 454};
1268
GFX_SSE2_ALIGN(const short color_constants_6[8]) = {11382, 11382, 11382, 11382, 11382, 11382, 11382, 11382};
1253
1269
1254
METHODDEF(void)
1270
METHODDEF(void)
1255
ycc_rgb_convert_argb (j_decompress_ptr cinfo,
1271
ycc_rgb_convert_argb (j_decompress_ptr cinfo,
1256
                 JSAMPIMAGE input_buf, JDIMENSION input_row,
1272
                 JSAMPIMAGE input_buf, JDIMENSION input_row,
1257
                 JSAMPARRAY output_buf, int num_rows)
1273
                 JSAMPARRAY output_buf, int num_rows)
1258
{
1274
{
1259
  JDIMENSION num_cols = cinfo->output_width;
1275
  JDIMENSION num_cols = cinfo->output_width;
1260
  JSAMPLE * range_limit = cinfo->sample_range_limit;
1276
  JSAMPLE * range_limit = cinfo->sample_range_limit;
1261
1277
1278
/* Locals for SSE2 support */
1279
1280
#if defined(GFX_HAVE_SSE2_INTRINSICS) || defined(GFX_HAVE_SSE2_INTEL_MNEMONICS)
1281
  JSAMPROW inptr0, inptr1, inptr2, outptr;
1282
  JDIMENSION col;
1283
  __m128i row_Y, row_cb, row_cr, zeroes, ones;
1284
  __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
1285
  __m128i row_B, row_G, row_R;
1286
#endif /* GFX_HAVE_SSE2_INTRINSICS || GFX_HAVE_SSE2_INTEL_MNEMONICS */
1287
1262
  SHIFT_TEMPS
1288
  SHIFT_TEMPS
1263
1289
1264
  /* This is used if we don't have SSE2 */
1290
#ifdef GFX_HAVE_SSE2_INTEL_MNEMONICS
1291
1292
  /* See if SSE2 is available if we haven't done so */
1265
1293
1266
  while (--num_rows >= 0) {
1294
  if (SSE2Present == 0)
1267
    JSAMPROW inptr0 = input_buf[0][input_row];
1295
    SSE2Present = gfxPlatform::SSE2Support();
1268
    JSAMPROW inptr1 = input_buf[1][input_row];
1296
#endif /* GFX_HAVE_SSE2_INTEL_MNEMONICS */
1269
    JSAMPROW inptr2 = input_buf[2][input_row];
1297
1270
    input_row++;
1298
  if (SSE2Present == 1) {
1271
    PRUint32 *outptr = (PRUint32 *) *output_buf++;
1299
1272
    for (JDIMENSION col = 0; col < num_cols; col++) {
1300
    /* Load registers with constants if we're going to do at least one quad */
1273
      int y  = GETJSAMPLE(inptr0[col]);
1301
    
1274
      int cb = GETJSAMPLE(inptr1[col]);
1302
    if (num_cols >= 8) {
1275
      int cr = GETJSAMPLE(inptr2[col]);
1303
      zeroes = _mm_setzero_si128();
1276
      JSAMPLE * range_limit_y = range_limit + y;
1304
      ones = _mm_cmpeq_epi8(zeroes, zeroes);
1277
      /* Range-limiting is essential due to noise introduced by DCT losses. */
1305
    }
1278
      outptr[col] = 0xFF000000 |
1306
    
1279
                    ( range_limit_y[Cr_r_tab[cr]] << 16 ) |
1307
    while (--num_rows >= 0) {
1280
                    ( range_limit_y[((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))] << 8 ) |
1308
      inptr0 = input_buf[0][input_row];
1281
                    ( range_limit_y[Cb_b_tab[cb]] );
1309
      inptr1 = input_buf[1][input_row];
1310
      inptr2 = input_buf[2][input_row];
1311
      input_row++;
1312
      outptr = *output_buf++;
1313
      
1314
      /* YCbCr -> RGB using scaled multiplication */
1315
      
1316
      for (col = 0; col + 8 <= num_cols; col += 8) {
1317
        
1318
        /* Read a row of each color component */
1319
1320
        row_Y  = _mm_loadl_epi64((__m128i *) (inptr0 + col));
1321
        row_cb = _mm_loadl_epi64((__m128i *) inptr1);
1322
        row_cr = _mm_loadl_epi64((__m128i *) inptr2);
1323
        
1324
        /* Convert bytes to words */
1325
        
1326
        row_Y  = _mm_unpacklo_epi8(row_Y, zeroes);
1327
        row_cb = _mm_unpacklo_epi8(row_cb, zeroes);
1328
        row_cr = _mm_unpacklo_epi8(row_cr, zeroes);
1329
1330
        /* Compute B and R */
1331
1332
        tmp0 = _mm_sub_epi16(row_cb, *((__m128i *) color_constants_1));    /* cb - 128 */
1333
        tmp1 = _mm_sub_epi16(row_cr, *((__m128i *) color_constants_1));    /* cr - 128 */
1334
        tmp2 = _mm_slli_epi16(tmp0, 8);                                    /* (cb - 128) << 8 */
1335
        tmp3 = _mm_slli_epi16(tmp1, 8);                                    /* (cr - 128) << 8 */
1336
        tmp2 = _mm_mulhi_epi16(tmp2, *((__m128i *) color_constants_5));    /* (454 * ((cb - 128) << 8)) >> 16 */
1337
        tmp3 = _mm_mulhi_epi16(tmp3, *((__m128i *) color_constants_2));    /* (359 * ((cr - 128) << 8)) >> 16 */
1338
        row_B = _mm_add_epi16(tmp2, row_Y);                                /* B = y + (454 * ((cb - 128) << 8)) >> 16 */
1339
        row_R = _mm_add_epi16(tmp3, row_Y);                                /* R = y + (359 * ((cr - 128) << 8)) >> 16 */
1340
1341
        /* Compute G */
1342
1343
        tmp4 = _mm_mullo_epi16(row_cb, *((__m128i *) color_constants_3));    /* 88 * cb */
1344
        tmp5 = _mm_mullo_epi16(tmp1, *((__m128i *) color_constants_4));      /* 183 * (cr - 128) */
1345
        tmp4 = _mm_sub_epi16(tmp4, *((__m128i *) color_constants_6));        /* 88 * cb - (34806 - 128*256) */
1346
        tmp4 = _mm_add_epi16(tmp4, tmp5);                                    /* (88 * cb) + 183 * (cr - 128) - (34806 - 128*256) */
1347
        tmp4 = _mm_srai_epi16(tmp4, 8);                                      /* Shift the above right by 8 to divide by 256 */
1348
        row_G = _mm_sub_epi16(row_Y, tmp4);                                  /* G */
1349
1350
        /* Pack word to byte with unsigned saturation which range limits too */
1351
1352
        row_R = _mm_packus_epi16(row_R, zeroes);
1353
        row_G = _mm_packus_epi16(row_G, zeroes);
1354
        row_B = _mm_packus_epi16(row_B, zeroes);
1355
1356
        /* Pack horizontally */
1357
1358
        tmp0 = _mm_unpacklo_epi8(row_B, row_G);          /* ABAB ABAB ABAB ABAB        */
1359
        tmp1 = _mm_unpacklo_epi8(row_R, ones);           /* GRGR GRGR GRGR GRGR        */
1360
        tmp2 = _mm_unpacklo_epi16(tmp0, tmp1);           /* ARGB ARGB ARGB ARGB (low)  */
1361
        tmp3 = _mm_unpackhi_epi16(tmp0, tmp1);           /* ARGB ARGB ARGB ARGB (high) */
1362
1363
        /* Write out 32 bytes of ARGB */
1364
        
1365
        _mm_storel_epi64((__m128i *) outptr, tmp2);
1366
        _mm_storel_epi64((__m128i *) (outptr + 8), _mm_srli_si128(tmp2, 8));
1367
        _mm_storel_epi64((__m128i *) (outptr + 16), tmp3);
1368
        _mm_storel_epi64((__m128i *) (outptr + 24), _mm_srli_si128(tmp3, 8));
1369
        
1370
        /* Slide the pointers */
1371
        
1372
        /* inptr0 += 8; */
1373
        inptr1 += 8;
1374
        inptr2 += 8;
1375
        outptr += 32;
1376
      }
1377
1378
      /* Process remainder using scalar code */
1379
      for (; col < num_cols; col++) {
1380
        int y  = GETJSAMPLE(inptr0[col]);
1381
        int cb = GETJSAMPLE(inptr1[0]);
1382
        int cr = GETJSAMPLE(inptr2[0]);
1383
        inptr1++;
1384
        inptr2++;
1385
        JSAMPLE * range_limit_y = range_limit + y;
1386
        /* Range-limiting is essential due to noise introduced by DCT losses. */
1387
        *((PRUint32 *) outptr) = 0xFF000000 |
1388
                                 ( range_limit_y[Cr_r_tab[cr]] << 16 ) |
1389
                                 ( range_limit_y[((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))] << 8 ) |
1390
                                 ( range_limit_y[Cb_b_tab[cb]] );
1391
        outptr += 4;
1392
      }
1393
    }
1394
1395
  } else {
1396
1397
    /* This is used if we don't have SSE2 */
1398
1399
    while (--num_rows >= 0) {
1400
      JSAMPROW inptr0 = input_buf[0][input_row];
1401
      JSAMPROW inptr1 = input_buf[1][input_row];
1402
      JSAMPROW inptr2 = input_buf[2][input_row];
1403
      input_row++;
1404
      PRUint32 *outptr = (PRUint32 *) *output_buf++;
1405
      for (JDIMENSION col = 0; col < num_cols; col++) {
1406
        int y  = GETJSAMPLE(inptr0[col]);
1407
        int cb = GETJSAMPLE(inptr1[col]);
1408
        int cr = GETJSAMPLE(inptr2[col]);
1409
        JSAMPLE * range_limit_y = range_limit + y;
1410
        /* Range-limiting is essential due to noise introduced by DCT losses. */
1411
        outptr[col] = 0xFF000000 |
1412
                      ( range_limit_y[Cr_r_tab[cr]] << 16 ) |
1413
                      ( range_limit_y[((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))] << 8 ) |
1414
                      ( range_limit_y[Cb_b_tab[cb]] );
1415
      }
1282
    }
1416
    }
1283
  }
1417
  }
1284
}
1418
}
1285
1419
1286
1287
/**************** Inverted CMYK -> RGB conversion **************/
1420
/**************** Inverted CMYK -> RGB conversion **************/
1288
/*
1421
/*
1289
 * Input is (Inverted) CMYK stored as 4 bytes per pixel.
1422
 * Input is (Inverted) CMYK stored as 4 bytes per pixel.
1290
 * Output is RGB stored as 3 bytes per pixel.
1423
 * Output is RGB stored as 3 bytes per pixel.
1291
 * @param row Points to row buffer containing the CMYK bytes for each pixel in the row.
1424
 * @param row Points to row buffer containing the CMYK bytes for each pixel in the row.
1292
 * @param width Number of pixels in the row.
1425
 * @param width Number of pixels in the row.
1293
 */
1426
 */
1294
static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width)
1427
static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width)

Return to bug 416157