| OLD | NEW |
| 1 /* vim: set ts=8 sw=8 noexpandtab: */ | 1 /* vim: set ts=8 sw=8 noexpandtab: */ |
| 2 // qcms | 2 // qcms |
| 3 // Copyright (C) 2009 Mozilla Foundation | 3 // Copyright (C) 2009 Mozilla Foundation |
| 4 // Copyright (C) 1998-2007 Marti Maria | 4 // Copyright (C) 1998-2007 Marti Maria |
| 5 // | 5 // |
| 6 // Permission is hereby granted, free of charge, to any person obtaining | 6 // Permission is hereby granted, free of charge, to any person obtaining |
| 7 // a copy of this software and associated documentation files (the "Software"), | 7 // a copy of this software and associated documentation files (the "Software"), |
| 8 // to deal in the Software without restriction, including without limitation | 8 // to deal in the Software without restriction, including without limitation |
| 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, | 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 10 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e | 10 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e |
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 } | 693 } |
| 694 | 694 |
| 695 num_in_channels = read_u8(src, offset + 8); | 695 num_in_channels = read_u8(src, offset + 8); |
| 696 num_out_channels = read_u8(src, offset + 8); | 696 num_out_channels = read_u8(src, offset + 8); |
| 697 if (num_in_channels > MAX_CHANNELS || num_out_channels > MAX_CHANNELS) | 697 if (num_in_channels > MAX_CHANNELS || num_out_channels > MAX_CHANNELS) |
| 698 return NULL; | 698 return NULL; |
| 699 | 699 |
| 700 // We require 3in/out channels since we only support RGB->XYZ (or RGB->L
AB) | 700 // We require 3in/out channels since we only support RGB->XYZ (or RGB->L
AB) |
| 701 // XXX: If we remove this restriction make sure that the number of chann
els | 701 // XXX: If we remove this restriction make sure that the number of chann
els |
| 702 // is less or equal to the maximum number of mAB curves in qcmsint.
h | 702 // is less or equal to the maximum number of mAB curves in qcmsint.
h |
| 703 » // also check for clut_size overflow. | 703 » // also check for clut_size overflow. Also make sure it's != 0 |
| 704 if (num_in_channels != 3 || num_out_channels != 3) | 704 if (num_in_channels != 3 || num_out_channels != 3) |
| 705 return NULL; | 705 return NULL; |
| 706 | 706 |
| 707 // some of this data is optional and is denoted by a zero offset | 707 // some of this data is optional and is denoted by a zero offset |
| 708 // we also use this to track their existance | 708 // we also use this to track their existance |
| 709 a_curve_offset = read_u32(src, offset + 28); | 709 a_curve_offset = read_u32(src, offset + 28); |
| 710 clut_offset = read_u32(src, offset + 24); | 710 clut_offset = read_u32(src, offset + 24); |
| 711 m_curve_offset = read_u32(src, offset + 20); | 711 m_curve_offset = read_u32(src, offset + 20); |
| 712 matrix_offset = read_u32(src, offset + 16); | 712 matrix_offset = read_u32(src, offset + 16); |
| 713 b_curve_offset = read_u32(src, offset + 12); | 713 b_curve_offset = read_u32(src, offset + 12); |
| 714 | 714 |
| 715 // Convert offsets relative to the tag to relative to the profile | 715 // Convert offsets relative to the tag to relative to the profile |
| 716 // preserve zero for optional fields | 716 // preserve zero for optional fields |
| 717 if (a_curve_offset) | 717 if (a_curve_offset) |
| 718 a_curve_offset += offset; | 718 a_curve_offset += offset; |
| 719 if (clut_offset) | 719 if (clut_offset) |
| 720 clut_offset += offset; | 720 clut_offset += offset; |
| 721 if (m_curve_offset) | 721 if (m_curve_offset) |
| 722 m_curve_offset += offset; | 722 m_curve_offset += offset; |
| 723 if (matrix_offset) | 723 if (matrix_offset) |
| 724 matrix_offset += offset; | 724 matrix_offset += offset; |
| 725 if (b_curve_offset) | 725 if (b_curve_offset) |
| 726 b_curve_offset += offset; | 726 b_curve_offset += offset; |
| 727 | 727 |
| 728 if (clut_offset) { | 728 if (clut_offset) { |
| 729 assert (num_in_channels == 3); | 729 assert (num_in_channels == 3); |
| 730 // clut_size can not overflow since lg(256^num_in_channels) = 24
bits. | 730 // clut_size can not overflow since lg(256^num_in_channels) = 24
bits. |
| 731 for (i = 0; i < num_in_channels; i++) { | 731 for (i = 0; i < num_in_channels; i++) { |
| 732 clut_size *= read_u8(src, clut_offset + i); | 732 clut_size *= read_u8(src, clut_offset + i); |
| 733 if (clut_size == 0) { |
| 734 invalid_source(src, "bad clut_size"); |
| 735 } |
| 733 } | 736 } |
| 734 } else { | 737 } else { |
| 735 clut_size = 0; | 738 clut_size = 0; |
| 736 } | 739 } |
| 737 | 740 |
| 738 // 24bits * 3 won't overflow either | 741 // 24bits * 3 won't overflow either |
| 739 clut_size = clut_size * num_out_channels; | 742 clut_size = clut_size * num_out_channels; |
| 740 | 743 |
| 741 if (clut_size > MAX_CLUT_SIZE) | 744 if (clut_size > MAX_CLUT_SIZE) |
| 742 return NULL; | 745 return NULL; |
| 743 | 746 |
| 744 lut = malloc(sizeof(struct lutmABType) + (clut_size) * sizeof(float)); | 747 lut = malloc(sizeof(struct lutmABType) + (clut_size) * sizeof(float)); |
| 745 if (!lut) | 748 if (!lut) |
| 746 return NULL; | 749 return NULL; |
| 747 // we'll fill in the rest below | 750 // we'll fill in the rest below |
| 748 memset(lut, 0, sizeof(struct lutmABType)); | 751 memset(lut, 0, sizeof(struct lutmABType)); |
| 749 lut->clut_table = &lut->clut_table_data[0]; | 752 lut->clut_table = &lut->clut_table_data[0]; |
| 750 | 753 |
| 751 for (i = 0; i < num_in_channels; i++) { | 754 for (i = 0; i < num_in_channels; i++) { |
| 752 lut->num_grid_points[i] = read_u8(src, clut_offset + i); | 755 lut->num_grid_points[i] = read_u8(src, clut_offset + i); |
| 756 if (lut->num_grid_points[i] == 0) { |
| 757 invalid_source(src, "bad grid_points"); |
| 758 } |
| 753 } | 759 } |
| 754 | 760 |
| 755 // Reverse the processing of transformation elements for mBA type. | 761 // Reverse the processing of transformation elements for mBA type. |
| 756 lut->reversed = (type == LUT_MBA_TYPE); | 762 lut->reversed = (type == LUT_MBA_TYPE); |
| 757 | 763 |
| 758 lut->num_in_channels = num_in_channels; | 764 lut->num_in_channels = num_in_channels; |
| 759 lut->num_out_channels = num_out_channels; | 765 lut->num_out_channels = num_out_channels; |
| 760 | 766 |
| 761 if (matrix_offset) { | 767 if (matrix_offset) { |
| 762 // read the matrix if we have it | 768 // read the matrix if we have it |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 | 831 |
| 826 /* I'm not sure why the spec specifies a fixed number of entries for LUT
8 tables even though | 832 /* I'm not sure why the spec specifies a fixed number of entries for LUT
8 tables even though |
| 827 * they have room for the num_entries fields */ | 833 * they have room for the num_entries fields */ |
| 828 if (type == LUT8_TYPE) { | 834 if (type == LUT8_TYPE) { |
| 829 num_input_table_entries = 256; | 835 num_input_table_entries = 256; |
| 830 num_output_table_entries = 256; | 836 num_output_table_entries = 256; |
| 831 entry_size = 1; | 837 entry_size = 1; |
| 832 } else if (type == LUT16_TYPE) { | 838 } else if (type == LUT16_TYPE) { |
| 833 num_input_table_entries = read_u16(src, offset + 48); | 839 num_input_table_entries = read_u16(src, offset + 48); |
| 834 num_output_table_entries = read_u16(src, offset + 50); | 840 num_output_table_entries = read_u16(src, offset + 50); |
| 841 if (num_input_table_entries == 0 || num_output_table_entries ==
0) { |
| 842 invalid_source(src, "Bad channel count"); |
| 843 return NULL; |
| 844 } |
| 835 entry_size = 2; | 845 entry_size = 2; |
| 836 } else { | 846 } else { |
| 837 assert(0); // the caller checks that this doesn't happen | 847 assert(0); // the caller checks that this doesn't happen |
| 838 invalid_source(src, "Unexpected lut type"); | 848 invalid_source(src, "Unexpected lut type"); |
| 839 return NULL; | 849 return NULL; |
| 840 } | 850 } |
| 841 | 851 |
| 842 in_chan = read_u8(src, offset + 8); | 852 in_chan = read_u8(src, offset + 8); |
| 843 out_chan = read_u8(src, offset + 9); | 853 out_chan = read_u8(src, offset + 9); |
| 844 grid_points = read_u8(src, offset + 10); | 854 grid_points = read_u8(src, offset + 10); |
| 845 | 855 |
| 846 clut_size = pow(grid_points, in_chan); | 856 clut_size = pow(grid_points, in_chan); |
| 847 if (clut_size > MAX_CLUT_SIZE) { | 857 if (clut_size > MAX_CLUT_SIZE) { |
| 858 invalid_source(src, "CLUT too large"); |
| 848 return NULL; | 859 return NULL; |
| 849 } | 860 } |
| 850 | 861 |
| 851 if (in_chan != 3 || out_chan != 3) { | 862 if (in_chan != 3 || out_chan != 3) { |
| 863 invalid_source(src, "CLUT only supports RGB"); |
| 852 return NULL; | 864 return NULL; |
| 853 } | 865 } |
| 854 | 866 |
| 855 lut = malloc(sizeof(struct lutType) + (num_input_table_entries * in_chan
+ clut_size*out_chan + num_output_table_entries * out_chan)*sizeof(float)); | 867 lut = malloc(sizeof(struct lutType) + (num_input_table_entries * in_chan
+ clut_size*out_chan + num_output_table_entries * out_chan)*sizeof(float)); |
| 856 if (!lut) { | 868 if (!lut) { |
| 869 invalid_source(src, "CLUT too large"); |
| 857 return NULL; | 870 return NULL; |
| 858 } | 871 } |
| 859 | 872 |
| 860 /* compute the offsets of tables */ | 873 /* compute the offsets of tables */ |
| 861 lut->input_table = &lut->table_data[0]; | 874 lut->input_table = &lut->table_data[0]; |
| 862 lut->clut_table = &lut->table_data[in_chan*num_input_table_entries]; | 875 lut->clut_table = &lut->table_data[in_chan*num_input_table_entries]; |
| 863 lut->output_table = &lut->table_data[in_chan*num_input_table_entries + c
lut_size*out_chan]; | 876 lut->output_table = &lut->table_data[in_chan*num_input_table_entries + c
lut_size*out_chan]; |
| 864 | 877 |
| 865 lut->num_input_table_entries = num_input_table_entries; | 878 lut->num_input_table_entries = num_input_table_entries; |
| 866 lut->num_output_table_entries = num_output_table_entries; | 879 lut->num_output_table_entries = num_output_table_entries; |
| 867 » lut->num_input_channels = read_u8(src, offset + 8); | 880 » lut->num_input_channels = in_chan; |
| 868 » lut->num_output_channels = read_u8(src, offset + 9); | 881 » lut->num_output_channels = out_chan; |
| 869 » lut->num_clut_grid_points = read_u8(src, offset + 10); | 882 » lut->num_clut_grid_points = grid_points; |
| 870 lut->e00 = read_s15Fixed16Number(src, offset+12); | 883 lut->e00 = read_s15Fixed16Number(src, offset+12); |
| 871 lut->e01 = read_s15Fixed16Number(src, offset+16); | 884 lut->e01 = read_s15Fixed16Number(src, offset+16); |
| 872 lut->e02 = read_s15Fixed16Number(src, offset+20); | 885 lut->e02 = read_s15Fixed16Number(src, offset+20); |
| 873 lut->e10 = read_s15Fixed16Number(src, offset+24); | 886 lut->e10 = read_s15Fixed16Number(src, offset+24); |
| 874 lut->e11 = read_s15Fixed16Number(src, offset+28); | 887 lut->e11 = read_s15Fixed16Number(src, offset+28); |
| 875 lut->e12 = read_s15Fixed16Number(src, offset+32); | 888 lut->e12 = read_s15Fixed16Number(src, offset+32); |
| 876 lut->e20 = read_s15Fixed16Number(src, offset+36); | 889 lut->e20 = read_s15Fixed16Number(src, offset+36); |
| 877 lut->e21 = read_s15Fixed16Number(src, offset+40); | 890 lut->e21 = read_s15Fixed16Number(src, offset+40); |
| 878 lut->e22 = read_s15Fixed16Number(src, offset+44); | 891 lut->e22 = read_s15Fixed16Number(src, offset+44); |
| 879 | 892 |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 { | 1393 { |
| 1381 qcms_profile *profile = NULL; | 1394 qcms_profile *profile = NULL; |
| 1382 FILE *file = _wfopen(path, L"rb"); | 1395 FILE *file = _wfopen(path, L"rb"); |
| 1383 if (file) { | 1396 if (file) { |
| 1384 profile = qcms_profile_from_file(file); | 1397 profile = qcms_profile_from_file(file); |
| 1385 fclose(file); | 1398 fclose(file); |
| 1386 } | 1399 } |
| 1387 return profile; | 1400 return profile; |
| 1388 } | 1401 } |
| 1389 #endif | 1402 #endif |
| OLD | NEW |